Example #1
0
		def CalcInputR(sec):
			im = h.Impedance()
			im.loc(0.5, sec=sec)
			im.compute(0, 1) # 1st argument: impedance frequency to compute; 2nd argument: when ==1, the calculation considers the effect of differential gating states
			Rinput = im.input(0.5, sec=sec)
			
			return Rinput
def make_seg_df(cell):
    seg_locs = cell.morphology.seg_coords['p05']
    px = seg_locs[0]
    py = seg_locs[1]
    pz = seg_locs[2]
    df = pd.DataFrame()
    i = 0
    j = 0
    lens = []
    diams = []
    bmtk_ids = []
    sec_ids = []
    full_names = []
    xs = []
    parts = []
    distances = []
    elec_distances = []
    h.distance(sec=cell.hobj.soma[0])
    zz = h.Impedance()
    zz.loc(cell.hobj.soma[0](0.5))
    zz.compute(25, 1)

    for sec in cell.hobj.all:
        for seg in sec:
            lens.append(seg.sec.L)
            diams.append(seg.sec.diam)
            distances.append(h.distance(seg))
            bmtk_ids.append(i)
            xs.append(seg.x)
            fullsecname = sec.name()
            sec_ids.append(int(fullsecname.split("[")[2].split("]")[0]))
            sec_type = fullsecname.split(".")[1][:4]
            parts.append(sec_type)
            full_names.append(str(seg))
            elec_distances.append(zz.ratio(seg))
            j += 1
        i += 1

    df["BMTK ID"] = bmtk_ids
    df["X"] = xs
    df["Type"] = parts
    df["Sec ID"] = sec_ids
    df["Distance"] = distances
    df["Section_L"] = lens
    df["Section_diam"] = diams
    df["Coord X"] = px
    df["Coord Y"] = py
    df["Coord Z"] = pz
    df["Elec_distance"] = elec_distances

    df.to_csv("Segments.csv", index=False)
Example #3
0
def compare_pas(filename, param_list=None):
    """Change input resistance by adjusting the passive leak channel.
    The leak channel has K+, Na+, and Cl- conductances with a set ratio (see config.hoc).
    Calling h.changePas(<new passive K conductance>) respects the ratio.
    Saved filenames include the relative change in PAS, the Input Resistance, the steady-state cli (at 0 input),
    and membrane potential.
    """
    rel_gkpbar = param_list
    if not rel_gkpbar:
        rel_gkpbar = [0.8, 1, 1.2, 1.5]
    print("rel_gkpbar:{}".format(rel_gkpbar))
    load_file(filename)
    # list of (exc,inh) synapses numbers
    imp = h.Impedance()
    imp.loc(0.5, sec=h.soma)
    for p in rel_gkpbar:
        h.changePas(h.g_pas_k_config*p)
        vm, cli = get_base_vm_cli(filename, compartment=h.soma)
        imp.compute(0, 1)  # calculate impedance at 0 Hz (i.e. resistance)
        ir = imp.input(0.5, sec=h.soma)  # input resistance at 0.5
        print("when p={}, Rm={}, [Cl]i={}, and Vm={}".format(p, ir, cli, vm))
        save_run("{}_[{},{:.2f},{:.2f},{:.2f}]".format(filename, p, ir, cli, vm))
Example #4
0
def measure_input_impedance_of_subtree(subtree_root_section, frequency):
    '''measures the input impedance of the subtree with the given root section

    (at the "0" tip, the soma-proximal end),
    returns the Impedance hoc object and the input impedance as a complex value
    '''

    imp_obj = h.Impedance()
    CLOSE_TO_SOMA_EDGE = 0
    # sets origin for impedance calculations (soma-proximal end of root section)
    imp_obj.loc(CLOSE_TO_SOMA_EDGE, sec=subtree_root_section)

    # computes transfer impedance from every segment in the model in relation
    # to the origin location above
    imp_obj.compute(frequency + 1 / 9e9, 0)

    # in Ohms (impedance measured at soma-proximal end of root section)
    root_input_impedance = imp_obj.input(CLOSE_TO_SOMA_EDGE,
                                         sec=subtree_root_section) * 1000000
    root_input_phase = imp_obj.input_phase(CLOSE_TO_SOMA_EDGE,
                                           sec=subtree_root_section)
    # creates a complex impedance value out of the given polar coordinates
    root_input_impedance = cmath.rect(root_input_impedance, root_input_phase)
    return imp_obj, root_input_impedance
Example #5
0
def test_partrans():

    # no transfer targets or sources.
    mkmodel(4)
    run()

    # invalid source or target sid.
    if 0 in model[0]:
        cell = model[0][0]
        s = cell.soma
        expect_error(pc.source_var, (s(0.5)._ref_v, -1), sec=s)
        expect_error(pc.target_var, (cell.ic, cell.ic._ref_amp, -1))

    # target with no source.
    if pc.gid_exists(1):
        cell = pc.gid2cell(1)
        pc.target_var(cell.ic, cell.ic._ref_amp, 1)
    expect_error(run, ())

    mkmodel(4)

    # source with no target (not an error).
    if pc.gid_exists(1):
        cell = pc.gid2cell(1)
        pc.source_var(cell.soma(0.5)._ref_v, 1, sec=cell.soma)
    run()

    # No point process for target
    if pc.gid_exists(1):
        cell = pc.gid2cell(1)
        pc.target_var(cell.vc._ref_amp3, 1)
    try:
        run()  # ok if test_fast_imem.py not prior
    except:
        pass
    pc.nthread(2)
    expect_error(run, ())  # Do not know the POINT_PROCESS target
    pc.nthread(1)

    # Wrong sec for source ref and wrong point process for target ref.
    mkmodel(1)
    if pc.gid_exists(0):
        cell = pc.gid2cell(0)
        sec = h.Section(name="dend")
        expect_error(pc.source_var, (cell.soma(0.5)._ref_v, 1), sec=sec)
        expect_error(pc.source_var, (cell.soma(0.5)._ref_nai, 2), sec=sec)
        del sec
        expect_error(pc.target_var, (cell.ic, cell.vc._ref_amp3, 1))
        # source sid already in use
        expect_error(pc.source_var, (cell.soma(0.5)._ref_nai, 1),
                     sec=cell.soma)

    # partrans update: could not find parameter index

    # pv2node checks the parent
    mkmodel(1)
    s1 = h.Section(name="dend")
    s2 = h.Section(name="soma")
    ic = h.IClamp(s1(0.5))
    pc.source_var(s1(0)._ref_v, rank, sec=s1)
    pc.target_var(ic, ic._ref_amp, rank)
    run()
    assert s1(0).v == ic.amp
    """
  # but following changes the source node and things get screwed up
  # because of continuing to use a freed Node*. The solution is
  # beyond the scope of this pull request and would involve replacing
  # description in terms of Node* with (Section*, arc_position)
  s1.connect(s2(.5))
  run()
  print(s1(0).v, ic.amp)
  assert(s1(0).v == ic.amp)
  """
    # non_vsrc_update property disappears from Node*
    s1.insert("pas")  # not allowed to uninsert ions :(
    pc.source_var(s1(0.5)._ref_e_pas, rank + 10, sec=s1)
    pc.target_var(ic, ic._ref_delay, rank + 10)
    run()
    assert s1(0.5).e_pas == ic.delay
    s1.uninsert("pas")
    expect_error(run, ())
    teardown()
    del ic, s1, s2

    # missing setup_transfer
    mkmodel(4)
    transfer1()
    expect_error(h.finitialize, (-65, ))

    # round robin transfer v to ic.amp and vc.amp1, nai to vc.amp2
    ncell = 5
    mkmodel(ncell)
    transfer1()
    init_values()
    run()
    check_values()

    # nrnmpi_int_alltoallv_sparse
    h.nrn_sparse_partrans = 1
    mkmodel(5)
    transfer1()
    init_values()
    run()
    check_values()
    h.nrn_sparse_partrans = 0

    # impedance error (number of gap junction not equal to number of pc.transfer_var)
    imp = h.Impedance()
    if 0 in model[0]:
        imp.loc(model[0][0].soma(0.5))
    expect_error(imp.compute, (1, 1))
    del imp

    # For impedance, pc.target_var requires that its first arg be a reference to the POINT_PROCESS"
    mkmodel(2)
    if pc.gid_exists(0):
        cell = pc.gid2cell(0)
        pc.source_var(cell.soma(0.5)._ref_v, 1000, sec=cell.soma)
        cell.hgap[1] = h.HGap(cell.soma(0.5))
        pc.target_var(cell.hgap[1], cell.hgap[1]._ref_e, 1001)
    if pc.gid_exists(1):
        cell = pc.gid2cell(1)
        pc.source_var(cell.soma(0.5)._ref_v, 1001, sec=cell.soma)
        cell.hgap[0] = h.HGap(cell.soma(0.5))
        pc.target_var(cell.hgap[0], cell.hgap[0]._ref_e, 1000)
    pc.setup_transfer()
    imp = h.Impedance()
    h.finitialize(-65)
    if pc.gid_exists(0):
        imp.loc(pc.gid2cell(0).soma(0.5))
    expect_error(imp.compute, (10, 1, 100))
    del imp, cell

    # impedance
    ncell = 5
    mkmodel(ncell)
    mkgaps(list(range(ncell - 1)))
    pc.setup_transfer()
    imp = h.Impedance()
    h.finitialize(-65)
    if 0 in model[0]:
        imp.loc(model[0][0].soma(0.5))
    niter = imp.compute(10, 1, 100)
    if rank == 0:
        print("impedance iterations=%d" % niter)
    # tickle execution of target_ptr_update for one more line of coverage.
    if 0 in model[0]:
        model[0][0].hgap[1].loc(model[0][0].soma(0))
        model[0][0].hgap[1].loc(model[0][0].soma(0.5))
    niter = imp.compute(10, 1, 100)
    del imp

    # CoreNEURON gap file generation
    mkmodel(ncell)
    transfer1()

    # following is a bit tricky and need some user help in the docs.
    #  cannot be cache_efficient if general sparse matrix solver in effect.
    cvode = h.CVode()
    assert cvode.use_mxb(0) == 0
    assert cvode.cache_efficient(1) == 1

    pc.setup_transfer()
    h.finitialize(-65)
    pc.nrncore_write("tmp")

    # CoreNEURON: one thread empty of gaps
    mkmodel(1)
    transfer1()
    s = h.Section("dend")
    pc.set_gid2node(rank + 10, rank)
    pc.cell(rank + 10, h.NetCon(s(0.5)._ref_v, None, sec=s))
    pc.nthread(2)
    pc.setup_transfer()
    h.finitialize(-65)
    pc.nrncore_write("tmp")
    pc.nthread(1)
    teardown()
    del s

    # There are single thread circumstances where target POINT_PROCESS is needed
    s = h.Section("dend")
    pc.set_gid2node(rank, rank)
    pc.cell(rank, h.NetCon(s(0.5)._ref_v, None, sec=s))
    pc.source_var(s(0.5)._ref_v, rank, sec=s)
    ic = h.IClamp(s(0.5))
    pc.target_var(ic._ref_amp, rank)
    pc.setup_transfer()
    expect_error(h.finitialize, (-65, ))
    teardown()
    del ic, s

    # threads
    mkmodel(ncell)
    transfer1()
    pc.nthread(2)
    init_values()
    run()
    check_values()
    pc.nthread(1)

    # extracellular means use v = vm+vext[0]
    for cell in model[0].values():
        cell.soma.insert("extracellular")
    init_values()
    run()
    check_values()

    teardown()
from neuron import h as nrn
# nrn.nrn_load_dll('x86_64/.libs/libnrnmech.so')
# nrnivmodl h.mod kdr2.mod kca.mod cad2.mod it2.mod SlowCa.mod hh3.mod km.mod kap.mod
nrn.xopen("build_cell.hoc")
# nrn.ca_hot_zone()

import numpy as np
import matplotlib.pylab as plt

freq = np.logspace(-1.1, np.log(500.) / np.log(10), 50)
imped, phase = 0. * freq, 0. * freq

Z = nrn.Impedance(sec=nrn.soma)
Z.loc(0.5)

for i in range(len(freq)):
    Z.compute(freq[i], 0.5)
    imped[i] = Z.input(0.5, sec=nrn.soma)
    phase[i] = Z.input_phase(0.5, sec=nrn.soma)

fig, AX = plt.subplots(1, 2, figsize=(10, 3))
AX[0].loglog(freq, imped)
AX[1].semilogx(freq, -phase)
plt.show()

np.save('data/larkum_imped_data.npy', [freq, imped, phase])
Example #7
0
# run over all the compartments in the model
h.distance(0,0.5,sec=HCell.soma[0])
num_secs = len([sec for sec in HCell.all ])
bar = progressbar.ProgressBar(max_value=num_secs, widgets=[' [', progressbar.Timer(), '] ',
            progressbar.Bar(), ' (', progressbar.ETA(), ') ',    ])
for jx,sec in enumerate(HCell.all):

    dend_sref = h.SectionRef(sec = sec)

    Xs = [seg.x for seg in sec]
    Xs = Xs + [1]
    
    for x in Xs:
        h.finitialize(V_INIT)
        dist = h.distance(x,sec=sec)
        z = h.Impedance()
        z.loc(x,sec=sec)
        z.compute(0,1)
        IR = z.input(x,sec=sec)
        z.compute(FREQ,1)
        IMP = z.input(x,sec=sec)
        SynList = []
        ConList = []
        HCell.delete_spine() # delete the previous spines
        SynList,ConList = add_synapse_at_spine(1,dend_sref,x,SynList,ConList)
        run_and_save_simulation(dend_sref,x,on_spine=True)
        f_output.write("%g,%g,%g\n"%(IR,IMP,dist))
        
        SynList = []
        ConList = []
Example #8
0
    diam = 10
    L = 100/(PI*diam)
    insert pas
    g_pas = .001
    e_pas = -65
  }
}
endtemplate Cell
''')

ncell = 2
cells = {}
for gid in range(rank, ncell, nhost):
    cells[gid] = h.Cell()

imp = h.Impedance()
if 0 in cells: imp.loc(.5, sec=cells[0].soma)


def foo(freq):
    if rank == 0: print("impedance")
    # all ranks must participate in the compute
    imp.compute(freq, 1)

    for gid in cells:
        print("cell[%d].soma transfer %g" %
              (gid, imp.transfer(.5, sec=cells[gid].soma)))


if nhost == 1: foo(0)  #should print 1000.0 and 0.0
Example #9
0
def simulate_single_param(args):
    """
  Simulates a specific input parameter vector
  
  :param args: The parameters for the simulation: 
                 The list of excitatory presynpatic inputs,
                 The list of inhibitory presynpatic inputs,
                 and the input parameter dictionary
  :returns: The voltage trace of the simulation
  """
    from neuron import h
    from neuron import gui
    h.load_file("nrngui.hoc")
    h.load_file("import3d.hoc")

    param_dict = args[0]

    hoc_code = '''h("create soma")
h("access soma")
h("nseg = 1")
h("L = 20")
h("diam = 20")
h("insert pas")
h("cm = 1")
h("Ra = 150")
h("forall nseg = 1")
h("forall e_pas = -90")

h("soma insert Ca_LVAst ")
h("soma insert Ca_HVA ")
h("soma insert SKv3_1 ")
h("soma insert SK_E2 ")
h("soma insert K_Tst ")
h("soma insert K_Pst ")
h("soma insert Nap_Et2 ")
h("soma insert NaTa_t")
h("soma insert CaDynamics_E2")
h("soma insert Ih")

h("ek = -85")
h("ena = 50")
h("gIhbar_Ih = 0.0002")
h("g_pas = 1.0 / 12000 ")
h("celsius = 36")
'''

    exec(hoc_code)
    exec('h("tstop = {}")'.format(simulation_length))
    exec('h("v_init = {}")'.format(v_init))

    for key in param_dict.keys():
        h(key + " = " + str(param_dict[key]))

    iclamp = h.IClamp(0.5)
    iclamp.delay = 500
    iclamp.dur = 1400

    amp = 0.05
    iclamp.amp = amp
    im = h.Impedance()
    h("access soma")
    h("nseg = 1")
    im.loc(0.5)
    im.compute(0)
    Ri = im.input(0.5)

    semitrial_start = time.time()

    ### Set the protocol

    h.finitialize()

    ### Simulate!

    voltageVector = h.Vector()
    voltageVector.record(eval("h.soma(0.5)._ref_v"))
    timeVector = h.Vector()
    timeVector.record(h._ref_t)

    h.run()

    timeVector = np.array(timeVector)
    voltageVector = np.array(voltageVector)

    trace = {}
    trace['T'] = timeVector[4000:]
    trace['V'] = np.array(voltageVector)[4000:]
    trace['stim_start'] = [500]
    trace['stim_end'] = [1900]
    del voltageVector, timeVector
    return trace
Example #10
0
    diam = 10
    L = 100/(PI*diam)
    insert pas
    g_pas = .001
    e_pas = -30
  }
}
endtemplate Cell
''')

ncell = 2
cells = {}
for gid in range(rank, ncell, nhost):
  cells[gid] = h.Cell()

imp_ = h.Impedance()
if 0 in cells: imp_.loc(.5, sec=cells[0].soma)

def imp(freq):
  pc.setup_transfer()
  h.finitialize(-65)
  if rank == 0: print ("impedance")
  # all ranks must participate in the compute
  iter = imp_.compute(freq, 1)
  print("freq=%g iter=%g"% (freq, iter))

  for gid in cells:
    print ("cell[%d].soma transfer %g" %(gid, imp_.transfer(.5, sec=cells[gid].soma)))


def run(tstop):
def run_model(model,
              morph_file,
              path="human_spines_simulations/",
              file_prefix="simulating_spines_"):
    print model
    HCell = create_model(model, morph_file)
    output_file = path + file_prefix + model + ".txt"
    f_output = open(output_file, 'w')
    f_output.write(
        "Spine,shaft_name,shaft_x,max_soma_v,max_shaft_v,max_spine_v,soma_v_integ,shaft_v_integ,spine_v_integ,ir_shaft,z_shaft,dist_shaft\n"
    )

    # run over all the compartments in the model
    h.distance(0, 0.5, sec=HCell.soma[0])
    num_secs = len([sec for sec in HCell.all])
    bar = progressbar.ProgressBar(max_value=num_secs,
                                  widgets=[
                                      ' [',
                                      progressbar.Timer(),
                                      '] ',
                                      progressbar.Bar(),
                                      ' (',
                                      progressbar.ETA(),
                                      ') ',
                                  ])

    for jx, sec in enumerate(HCell.all):
        dend_sref = h.SectionRef(sec=sec)
        Xs = [seg.x for seg in sec]
        Xs = Xs + [1]

        for x in Xs:
            h.finitialize(V_INIT)
            dist = h.distance(x, sec=sec)
            z = h.Impedance()
            z.loc(x, sec=sec)
            z.compute(0, 1)
            IR = z.input(x, sec=sec)
            z.compute(FREQ, 1)
            IMP = z.input(x, sec=sec)
            SynList = []
            ConList = []

            HCell.delete_spine()  # delete the previous spines
            SynList, ConList = add_synapse_at_spine(HCell, 1, dend_sref, x,
                                                    SynList, ConList)
            run_and_save_simulation(HCell,
                                    dend_sref,
                                    x,
                                    f_output,
                                    on_spine=True)
            f_output.write("%g,%g,%g\n" % (IR, IMP, dist))

            HCell.delete_spine()
            SynList = []
            ConList = []
            SynList, ConList = add_synapse_at_shaft(HCell, 1, dend_sref, x,
                                                    SynList, ConList)
            run_and_save_simulation(HCell,
                                    dend_sref,
                                    x,
                                    f_output,
                                    on_spine=False)
            f_output.write("%g,%g,%g\n" % (IR, IMP, dist))
        bar.update(jx)

    f_output.close()
Example #12
0
def test_deleted_sec():
    for sec in h.allsec():
        h.delete_section(sec=sec)
    s = h.Section()
    s.insert("hh")
    seg = s(0.5)
    ic = h.IClamp(seg)
    mech = seg.hh
    rvlist = [rv for rv in mech]
    vref = seg._ref_v
    gnabarref = mech._ref_gnabar
    sec_methods_ok = set([s.cell, s.name, s.hname, s.same, s.hoc_internal_name])
    sec_methods_chk = set(
        [
            getattr(s, n)
            for n in dir(s)
            if "__" not in n
            and type(getattr(s, n)) == type(s.x3d)
            and getattr(s, n) not in sec_methods_ok
        ]
    )
    seg_methods_chk = set(
        [
            getattr(seg, n)
            for n in dir(seg)
            if "__" not in n and type(getattr(seg, n)) == type(seg.area)
        ]
    )
    mech_methods_chk = set(
        [
            getattr(mech, n)
            for n in dir(mech)
            if "__" not in n and type(getattr(mech, n)) == type(mech.segment)
        ]
    )
    rv_methods_chk = set(
        [
            getattr(rvlist[0], n)
            for n in dir(rvlist[0])
            if "__" not in n and type(getattr(rvlist[0], n)) == type(rvlist[0].name)
        ]
    )
    rv_methods_chk.remove(rvlist[0].name)
    h.delete_section(sec=s)

    for methods in [sec_methods_chk, seg_methods_chk, mech_methods_chk, rv_methods_chk]:
        for m in methods:
            # Most would fail because of no args, but expect a check
            # for valid section first.
            words = str(m).split()
            print("m is " + words[4] + "." + words[2])
            expect_err("m()")

    assert str(s) == "<deleted section>"
    assert str(seg) == "<segment of deleted section>"
    assert str(mech) == "<mechanism of deleted section>"
    expect_err("h.sin(0.0, sec=s)")
    expect_err("print(s.L)")
    expect_err("s.L = 100.")
    expect_err("s.nseg")
    expect_err("s.nseg = 5")
    expect_err("print(s.v)")
    expect_err("print(s.orientation())")
    expect_err("s.insert('pas')")
    expect_err("s.insert(h.pas)")
    expect_err("s(.5)")
    expect_err("s(.5).v")
    expect_err("seg.v")
    expect_err("seg._ref_v")
    expect_err("s(.5).v = -65.")
    expect_err("seg.v = -65.")
    expect_err("seg.gnabar_hh")
    expect_err("mech.gnabar")
    expect_err("seg.gnabar_hh = .1")
    expect_err("mech.gnabar = .1")
    expect_err("rvlist[0][0]")
    expect_err("rvlist[0][0] = .1")
    expect_err("for sg in s: pass")
    expect_err("for m in seg: pass")
    expect_err("for r in mech: pass")

    assert s == s
    # See https://github.com/neuronsimulator/nrn/issues/1343
    if sys.version_info >= (3, 8):
        expect_err("dir(s)")
        expect_err("dir(seg)")
        expect_err("dir(mech)")
    assert type(dir(rvlist[0])) == list
    expect_err("help(s)")
    expect_err("help(seg)")
    expect_err("help(mech)")
    help(rvlist[0])  # not an error since it does not access s

    dend = h.Section()
    expect_err("dend.connect(s)")
    expect_err("dend.connect(seg)")

    # Note vref and gnabarref if used may cause segfault or other indeterminate result

    assert ic.get_segment() == None
    assert ic.has_loc() == 0.0
    expect_err("ic.get_loc()")
    expect_err("ic.amp")
    expect_err("ic.amp = .001")
    ic.loc(dend(0.5))
    assert ic.get_segment() == dend(0.5)

    imp = h.Impedance()
    expect_err("imp.loc(seg)")
    expect_err("h.distance(0, seg)")
    expect_hocerr(imp.loc, (seg,))
    expect_hocerr(h.distance, (0, seg))

    del ic, imp, dend
    locals()

    return s, seg, mech, rvlist, vref, gnabarref
Example #13
0
File: BAP.py Project: asuhag/HINT
def simulate_single_param(args):  
  """
  Simulates a specific input parameter vector
  
  :param args: The parameters for the simulation: 
                 The list of excitatory presynpatic inputs,
                 The list of inhibitory presynpatic inputs,
                 and the input parameter dictionary
  :returns: The voltage trace of the simulation
  """   
  from neuron import h
  from neuron import gui
  h.load_file("nrngui.hoc")
  h.load_file("import3d.hoc")
  
  E_events_list = args[0]
  I_events_list = args[1]
  param_dict = args[2]  
  
  action_potential_at_soma = pickle.load(open('action_potential_at_soma.pickle', 'rb'))
  
  hoc_code = '''h("create soma")
h("access soma")
h("nseg = 1")
h("L = 20")
h("diam = 20")
h("insert pas")
h("cm = 1")
h("Ra = 150")
h("forall nseg = 1")
h("forall e_pas = -90")
h("soma insert Ca_LVAst")
h("soma insert Ca_HVA")
h("soma insert SKv3_1") 
h("soma insert SK_E2 ")
h("soma insert NaTa_t")
h("soma insert CaDynamics_E2")
h("soma insert Im ")
h("soma insert Ih")
h("ek = -85")
h("ena = 50")
h("gIhbar_Ih = 0.0128597")
h("g_pas = 1.0 / 12000 ")
h("celsius = 36")
'''
  
  exec(hoc_code)
  exec('h("tstop = {}")'.format(simulation_length))
  exec('h("v_init = {}")'.format(v_init))
  
  im = h.Impedance()
  h("access soma")
  im.loc(0.5)
  im.compute(0)
  Ri = im.input(0.5)

  h("access soma")
  h("nseg = 1")
  eSynlist = []
  eNetconlist = []
  iSynlist = []
  iNetconlist = []
  E_vcs = []
  I_vcs = []

  eSynlist.append(h.ProbAMPANMDA2_RATIO(0.5))  
  eSynlist[-1].gmax = 0.0004
  eSynlist[-1].mgVoltageCoeff = 0.08

  iSynlist.append(h.ProbUDFsyn2_lark(0.5))
  iSynlist[-1].tau_r = 0.18
  iSynlist[-1].tau_d = 5
  iSynlist[-1].e = - 80
  iSynlist[-1].gmax = 0.001
    
  
  semitrial_start = time.time()
  
  for key in param_dict.keys():
    if key is not "rate_E" and key is not "rate_I":
      h(key + " = " + str(param_dict[key]))
  
  E_events = np.array(E_events_list)[np.argmin(np.abs(np.array(E_events_list).mean(axis=1) - param_dict["rate_E"] / 1000.0))]
  I_events = np.array(I_events_list)[np.argmin(np.abs(np.array(I_events_list).mean(axis=1) - param_dict["rate_I"] / 1000.0))]

  E_vcs_events = []
  I_vcs_events = []
  E_vcs = h.VecStim()
  I_vcs = h.VecStim()

  I_vcs_events.append(h.Vector())
  events = np.where(I_events[:])[0] + 100
  for event in events:
    I_vcs_events[-1].append(event)

  E_vcs_events.append(h.Vector())
  events = np.where(E_events[:])[0] + 100
  for event in events:
    E_vcs_events[-1].append(event)
  
  eNetconlist = h.NetCon(E_vcs, eSynlist[-1])
  eNetconlist.weight[0] = 1
  eNetconlist.delay = 0
  E_vcs.play(E_vcs_events[-1])
  
  iNetconlist = h.NetCon(I_vcs, iSynlist[-1])
  iNetconlist.weight[0] = 1
  iNetconlist.delay = 0
  I_vcs.play(I_vcs_events[-1])

  ### Set the protocol
  
  h.finitialize()
  
  ### Simulate!
  
  prev_voltageVector = h.Vector()
  prev_voltageVector.record(eval("h.soma(0.5)._ref_v"))
  prev_timeVector = h.Vector()
  prev_timeVector.record(h._ref_t)

  h.tstop = 160
  h.run()
  h.tstop = 200

  voltageVector = h.Vector()
  voltageVector.record(eval("h.soma(0.5)._ref_v"))
  timeVector = h.Vector()
  timeVector.record(h._ref_t)

  # Simulate AP

  h('''objref clamp
  soma clamp = new SEClamp(.5)
  {clamp.dur1 = 1e9 clamp.rs=1e9}
  ''')
  
  active_timeVector = h.Vector(np.arange(0, h.tstop, 0.025))
  active_ones = np.array([float(1e9)] * len(active_timeVector))
  play_vector = np.array([0.0] * len(active_timeVector))
  
  action_potential_neuron_vector = h.Vector(list(np.maximum(np.array(prev_voltageVector)[int(150 / 0.025) : int(154 / 0.025)], attenuate_action_potential(np.array(np.copy(action_potential_at_soma)), param_dict["percentage_AP"]))))
  
  active_ones[int(ap_time / 0.025) : int((ap_time + 4) / 0.025)] = 0.00001
  play_vector[int(ap_time / 0.025) : int((ap_time + 4) / 0.025)] = action_potential_neuron_vector
  
  active_ones = h.Vector(active_ones)
  play_vector = h.Vector(play_vector)
  
  play_vector.play(h.clamp._ref_amp1, active_timeVector, 0)
  active_ones.play(h.clamp._ref_rs, active_timeVector, 0)

  h.run()
  
  timeVector = np.array(timeVector)
  voltageVector = np.array(voltageVector)
  
  trace = {}
  trace['T'] = timeVector[4000:]
  trace['V'] = np.array(voltageVector)[4000:]

  h.clamp = None
  active_ones = None
  play_vector = None
  del voltageVector, timeVector, prev_voltageVector, prev_timeVector, action_potential_neuron_vector
  return trace