Пример #1
0
def update_section(sec, args):
    """Update section properties.

    args: {name: value} for parameters.

    The names `length`, `dia` and `RA` are mapped to L, diam and Ra
    respectively.

    `length`: section.L
    `dia`: section.diam
    `nseg`: section.nseg

    for all mechanisms, the entries should be:

    name: {field: value, ...}

    """
    sec.L = args.pop('length', sec.L)
    sec.diam = args.pop('dia', Q_(sec.diam, 'um')).to('um').m
    sec.Ra = args.pop('RA', Q_(sec.Ra, 'ohm*cm')).to('ohm*cm').m
    sec.nseg = args.pop('nseg', sec.nseg)
    for mech, params in args.items():
        for pname, pvalue in params.items():
            if pname.startswith('g'):
                val = pvalue.to('S/cm**2').m
            elif pname.startswith('e'):
                val = pvalue.to('mV').m
            else:
                raise Exception('Do not know how to handle {} {}'.format(
                    pname, pvalue))
            set_mech_param(sec, mech, pname, val)
Пример #2
0
def setup_voltage_clamp(cable,
                        vhold,
                        thold,
                        vpre,
                        tpre,
                        vclamp,
                        tclamp,
                        pos=0.0,
                        rs=Q_('0.001Mohm')):
    """Create a voltage clamp at `pos` location on `cable`.

    vhold: holding voltage (with unit, converted to mV)
    thold: holding period (with unit, converted to ms)
    vpre: prepulse voltage (with unit, converted to mV)
    tpre: prepulse period (with unit, converted to ms)
    vclamp: clamping voltage (with unit, converted to mV)
    tclamp: clamping period (with unit, converted to ms)
    rs: series resistance with clamp circuit  (with unit, converted to Mohm)
    """
    clamp = h.SEClamp(pos, sec=cable)
    clamp.rs = rs.to(ur.Mohm).m
    clamp.amp1 = vhold.to(ur.mV).m
    clamp.dur1 = thold.to(ur.ms).m
    clamp.amp2 = vpre.to(ur.mV).m
    clamp.dur2 = tpre.to(ur.ms).m
    clamp.amp3 = vclamp.to(ur.mV).m
    clamp.dur3 = tclamp.to(ur.ms).m
    return clamp
Пример #3
0
def make_kc_with_dynaclamp(kc_name,
                           kc_file,
                           inject,
                           tstart,
                           tend,
                           ggn_vm=None):
    """Read KC model from `kc_file`, inject current `inject` nA, apply
    dynamic clamp `ggn_vm`, which should be a 2D array with time (ms)
    in column 0, and voltage (mV) in column 1.

    """
    global model_dict
    kc = nu.create_cell(kc_name, filename=kc_file)
    model_dict[kc] = None
    iclamp = ephys.setup_current_clamp(kc.soma,
                                       pos=0.5,
                                       delay=Q_(tstart, 'ms'),
                                       duration=Q_((tend - tstart), 'ms'),
                                       amplitude=Q_(inject, 'nA'))
    model_dict[iclamp] = None
    ggn_g_vec = None
    if ggn_vm is not None:
        syn = h.GradedSyn(kc.soma(0.5))
        for attr, value in GGN_KC_SYN_PARAMS.items():
            setattr(syn, attr, value)
        model_dict[syn] = None
        ggn_comp = h.Section('ggn')
        model_dict[ggn_comp] = None
        h.setpointer(ggn_comp(0.5)._ref_v, 'vpre', syn)
        ggn_vm_vec = h.Vector(ggn_vm[:, 1])
        tvec = h.Vector(ggn_vm[:, 0])
        model_dict[tvec] = None
        # vec.play(var_reference, t, continuous) for interpolating
        ret = ggn_vm_vec.play(ggn_comp(0.5)._ref_v, tvec, 1)
        print('####', ret)
        model_dict[ggn_vm_vec] = None
        ggn_g_vec = h.Vector()
        ggn_g_vec.record(syn._ref_g)
        model_dict[ggn_g_vec] = None
    kc_vm_vec = h.Vector()
    kc_vm_vec.record(kc.soma(0.5)._ref_v)
    model_dict[kc_vm_vec] = None
    print('Built model')
    return (kc_vm_vec, ggn_g_vec)
Пример #4
0
def create_mechs(param_dict):
    """Create mechanisms from parameter dictionary. It should be a dict of
    dict like: {name: {'gbar': gbar_quantity}} except for passive conductance
    `pas`, which must have {'g': gpas_quantity, 'e': epas_quantity}

    Returns: a dict of {name: ephys.Mechanism}
    """
    ret = {}
    for name, params in param_dict.items():
        if name == 'pas':
            gpas = Q_(params['g'])
            epas = Q_(params['e'])
            mech = Mechanism(name, g=gpas.to('S/cm**2').m, e=epas.to('mV').m)
        else:
            mech = Mechanism(name, gbar=Q_(params['gbar']).to('S/cm**2').m)
        ret[name] = mech
    return ret
Пример #5
0
 def connect(self, sec, pos, synparams):
     self.synlist = []
     self.netcons = []
     count = synparams.get('count', 1)
     for ii in range(count):
         synapse = h.Exp2Syn(sec(pos))
         synapse.e = Q_(synparams.get('e', '-80mV')).to('mV').m
         synapse.tau1 = Q_(synparams.get('tau1', '13.33ms')).to('ms').m
         synapse.tau2 = Q_(synparams.get('tau2', '13.33ms')).to('ms').m
         thresh = Q_(synparams.get('threshold', '-20mV')).to('mV').m
         delay = Q_(synparams.get('delay', '0ms')).to('ms').m
         gmax = Q_(synparams.get('gmax', '1nS')).to('uS').m
         netcon = h.NetCon(self.vecstim, synapse, thresh, delay, gmax)
         self.synlist.append(synapse)
         self.netcons.append(netcon)
         logger.info('Connected IG->{} at {}'.format(sec.name(), pos))
         logger.info(
             'threshold: {}, delay: {}, gmax: {}, e: {}, tau1: {}, tau2: {}'
             .format(netcon.threshold, netcon.delay, netcon.weight[0],
                     synapse.e, synapse.tau1, synapse.tau2))
Пример #6
0
def create_pn_output(params):
    """This attempts to create inputs a KC receives from its presynaptic PNs
    References: Mazor and Laurent, 2005; Jortner, et al., 2007.

    Here the assumption is `odor_exc_frac` fraction of all PNs is
    activated by a specific odor, i.e. there firing rate goes up
    (exact formula in code).

    On the other hand, spont_exc_frac of the cells are spontaneously
    active.
    
    npn: total number of PNs

    odor_exc_frac: fraction of PNs that spike in response to odor

    spont_exc_frac: fraction of PNs that spike spontaneously

    stim_rate: baseline firing rate of a PN during odor stimulation

    spont_rate: baseline firing rate of a PN without odor 

    osc_freq: frequency of LFP oscillation


    osc_amp_scale: The amplitude of oscillation as a fraction of
    baseline firing rate (default 0.3 from data from 50000 PNs).
    

    Returns a list of array quantitities containing spike times of
    each PN.

    """
    onset = Q_(params['onset']).to('s').m
    duration = Q_(params['duration']).to('s').m
    tail = Q_(params['tail']).to('s').m
    delta = Q_(params['delta']).to('s').m
    npn = params['npn']
    odor_exc_frac = params['odor_exc_frac']
    spont_exc_frac = params['spont_exc_frac']
    odor_inh_frac = params['odor_inh_frac']
    stim_rate = Q_(params['stim_rate']).to('Hz').m
    spont_rate = Q_(params['spont_rate']).to('Hz').m
    osc_freq = Q_(params['osc_freq']).to('Hz').m
    osc_amp_scale = params['osc_amp_scale']

    assert (odor_exc_frac + odor_inh_frac) <= 1

    spont_amp = spont_rate * osc_amp_scale
    stim_amp = stim_rate * osc_amp_scale
    # Rate function for spontaneously active, excited by odor
    rate_fn_spont_odor = lambda t: \
                         stim_rate + stim_amp * np.sin(2 * np.pi * osc_freq * t) \
                         if (onset < t < (onset + duration)) \
                            else spont_rate + spont_amp * np.sin(2 * np.pi * osc_freq * t)
    # Odor inhibited, but spontaneously active
    rate_fn_odor_inh = lambda t: \
                       0.0 if (onset < t < (onset + duration)) \
                       else spont_rate + spont_amp * np.sin(2 * np.pi * osc_freq * t)
    # Rate function for spontaneously active, unaffected by odor
    rate_fn_spont = lambda t: \
                    spont_rate + spont_amp * np.sin(2 * np.pi * osc_freq * t)
    # rate function for spontaneously silent, activated by odor
    rate_fn_odor = lambda t: \
                   stim_rate + stim_amp * np.sin(2 * np.pi * osc_freq * t) \
                   if (onset < t < (onset + duration)) \
                      else 0.0
    n_spont_odor = int(npn * spont_exc_frac * odor_exc_frac +
                       0.5)  # spontanously active, excited by odor
    n_odor = int(npn * (1 - spont_exc_frac) * odor_exc_frac +
                 0.5)  # silent, activated by odor
    n_odor_inh = int(npn * spont_exc_frac * odor_inh_frac +
                     0.5)  # spontaneously active inhibited by odor
    n_spont = int(npn * spont_exc_frac * (1 - odor_exc_frac - odor_inh_frac) +
                  0.5)
    # Ignore those that are neither spontaneously active nor activated
    # by a given odor: how many such PNs?
    pn_output = []
    start = timer()
    for ii in range(n_spont_odor):
        spike_times = nhpp.nhpp_thinning(rate_fn_spont_odor,
                                         onset + duration + tail, delta)
        pn_output.append(Q_(np.array(spike_times), 's'))
    for ii in range(n_odor):
        spike_times = nhpp.nhpp_thinning(rate_fn_odor, onset + duration + tail,
                                         delta)
        pn_output.append(Q_(np.array(spike_times), 's'))
    for ii in range(n_spont):
        spike_times = nhpp.nhpp_thinning(rate_fn_spont,
                                         onset + duration + tail, delta)
        pn_output.append(Q_(np.array(spike_times), 's'))
    for ii in range(n_odor_inh):
        spike_times = nhpp.nhpp_thinning(rate_fn_odor_inh,
                                         onset + duration + tail, delta)
        pn_output.append(Q_(np.array(spike_times), 's'))
    end = timer()
    logger.info('Time to create {} PN spiketrains {} s'.format(
        len(pn_output), end - start))
    silent = npn - len(pn_output)
    for ii in range(silent):
        pn_output.append(Q_(np.array([]), 's'))
    return pn_output
Пример #7
0
def create_shifting_response(params):
    """Create a response pattern with a shifting window into PN population
    over the LFP cycles.

    The step by step process to arrive at this design is in
    try_pn_output.ipynb.
    
    params should have the following key value pairs:

    onset: stimulus / activity onset 
    duration: duration of stimulus
    offdur: duration of off response
    tail: simulation time after the stimulus is over
    trials(=1): number of trials (only `tail` interval between successive stimuli.
    delta: interval at which the Poisson rate is considered.
    npn(=830): total number of PNs    
    odor_exc_shift(=0.1): fraction of excited PN changing state in each LFP cycle
    stim_rate(=20.0Hz): firing rate of excited PN upon odor, i.e. 1 spike in 50 ms    
    spont_rate(=2.6Hz): spontaneous firing rate of a PN
    osc_freq(=20.0Hz): LFP oscillation frequency    
    start_frac: fraction of cells in each group that start spiking simultaneously at the excitation phase of the group

    Returns: 

    pn_spikes - list of lists: i-th entry is a list spike
    times of i-th PN.

    clusters - dict: list of PNs mapped to their stimulus response
    start time. The entries against off response time include bith EI
    and II PNs.

    response_types  - dict: {
      'EE': indices of PNs that spike throughout odor presentation,
      'EI': indices of PNs that spike during first half of odor presentation,
      'IE': indices of PNs that spike during last half of odor presentation,
      'II': indices of PNs that do not spike during  of odor presentation
      'U': spntaneously active and unresponsive to odor stimulus
    }

    """
    npn = params['npn']
    lfp_bin = 50e-3  # second
    spont_rate = params['spont_rate'].to('Hz').m
    delta = params['delta'].to('s').m
    onset = params['onset'].to('s').m
    dur = params['duration'].to('s').m
    tail = params['tail'].to('s').m
    offdur = params['offdur'].to('s').m
    osc_freq = params['osc_freq'].to('Hz').m
    stim_rate = params['stim_rate'].to('Hz').m
    osc_amp_scale = params['osc_amp_scale']
    start_frac = params['start_frac']
    # Indices of different kinds of PNs.
    unresponsive = range(0, int(npn / 3.0))
    EE = list(
        range(unresponsive[-1] + 1, int(unresponsive[-1] + 1 + npn / 6.0)))
    EI = list(range(EE[-1] + 1, int(EE[-1] + 1 + npn / 6.0)))
    IE = list(range(EI[-1] + 1, int(EI[-1] + 1 + npn / 6.0)))
    II = list(range(IE[-1] + 1, npn))
    response_types = {
        'EE': EE,
        'EI': EI,
        'IE': IE,
        'II': II,
        'U': unresponsive
    }
    clusters = defaultdict(list)
    pn_spikes = []
    start = timer()
    # Spontaneous activity in all neurons
    spont_rate_fn = lambda t: spont_rate
    for ii in range(params['npn']):
        st1 = nhpp.nhpp_thinning(spont_rate_fn, onset, delta)
        st2 = nhpp.nhpp_thinning(spont_rate_fn, tail,
                                 delta) + onset + dur + offdur
        pn_spikes.append(list(st1) + list(st2))

    # Unresponsive PNs - first 1/3rd
    for jj, index in enumerate(unresponsive):
        pn_spikes[index] += list(
            nhpp.nhpp_thinning(spont_rate_fn, dur + offdur, delta) + onset)

    # Excited throughout odor

    # The rate function: python has dynamic binding - so ee_rate_fn
    # sees the value of `start` at evaluation time.
    ee_rate_fn = lambda t: stim_rate + osc_fn((dur - t) * stim_rate * osc_amp_scale / dur, osc_freq, t)  \
                 if  t > start else 0
    start = 0
    # After every `pnclus` PNs, increase the start time.
    pnclus = round(params['shifting_frac'] * len(EE))
    for jj, index in enumerate(EE):
        pn_spikes[index] += list(
            nhpp.nhpp_thinning(ee_rate_fn, dur, delta) + onset)
        clusters[onset + start].append(index)
        diff = jj - len(EE) * start_frac
        if (diff > 0) and (round(diff) % pnclus == 0):
            start += lfp_bin
    # PNs active only in first half of odour presentation
    ei_rate_fn = lambda t: stim_rate + osc_fn((dur - t) * stim_rate * osc_amp_scale / dur, osc_freq, t)  \
                 if  (t > start) and (t < dur/2.0) else 0
    start = 0
    pnclus = round(
        params['shifting_frac'] *
        len(EI))  # How many PNs should share the same starting time?
    for jj, index in enumerate(EI):
        pn_spikes[index] += list(
            nhpp.nhpp_thinning(ei_rate_fn, dur, delta) + onset)
        clusters[onset + start].append(index)
        diff = jj - len(EI) * start_frac
        if (diff > 0) and (round(diff) % pnclus == 0):
            start += lfp_bin

    # PNs active only in last half of odour presentation
    ie_rate_fn = lambda t: stim_rate + osc_fn((dur - t) * 2.0 * stim_rate * osc_amp_scale / dur, osc_freq, t) \
                 if  (t > start) else 0
    start = dur / 2.0
    pnclus = round(
        params['shifting_frac'] *
        len(IE))  # How many PNs should share the same starting time?
    for jj, index in enumerate(IE):
        pn_spikes[index] += list(
            nhpp.nhpp_thinning(ie_rate_fn, dur, delta) + onset)
        clusters[onset + start].append(index)
        diff = jj - len(IE) * start_frac
        if (diff > 0) and (round(diff) % pnclus == 0):
            start += lfp_bin
    # off response
    off_rate_fn =  lambda t: stim_rate + osc_fn((offdur - t) * stim_rate * osc_amp_scale / offdur, osc_freq, t)  \
                   if  (t > start) else 0
    start = 0
    pnclus = round(
        params['shifting_frac'] *
        len(EI))  # How many PNs should share the same starting time?
    for jj, index in enumerate(EI):
        pn_spikes[index] += list(
            nhpp.nhpp_thinning(off_rate_fn, offdur, delta) + onset + dur)
        clusters[onset + dur + start].append(index)
        diff = jj - len(EI) * start_frac
        if (diff > 0) and (round(diff) % pnclus == 0):
            start += lfp_bin
    start = 0
    pnclus = round(
        params['shifting_frac'] *
        len(II))  # How many PNs should share the same starting time?
    for jj, index in enumerate(II):
        pn_spikes[index] += list(
            nhpp.nhpp_thinning(off_rate_fn, offdur, delta) + onset + dur)
        clusters[onset + dur + start].append(index)
        diff = jj - len(II) * start_frac
        if (diff > 0) and (round(diff) % pnclus == 0):
            start += lfp_bin
    qst = []
    for ii, st in enumerate(pn_spikes):
        st = np.array(st)
        st.sort()
        qst.append(Q_(st, 's'))
    pn_spikes = qst
    end = timer()
    logger.info('Finished PN output creation in {} s'.format(end - start))
    return pn_spikes, clusters, response_types
Пример #8
0
def create_cable(name,
                 diameter,
                 length,
                 nseg,
                 RA,
                 CM=Q_('1.0uF/cm**2'),
                 mechs=[],
                 ek=Q_('-80.0mV'),
                 ena=Q_('60.0mV'),
                 eca=Q_('60.0mV'),
                 verbose=False):
    """Create a cable with specified dimeter, length and number of
    segments and insert the mechanisms in mechs list.

    Parameters:

    diameter (um):  cable diameter

    length (um): cable length

    nseg: number of segments to divide the cable into

    RA (ohm-cm): specific axial resistance

    CM (uF/cm2): specific membrane capacitance.

    mechs (Mechanism): list of mechanisms to be inserted into the
    section. You may want to update the properties later using
    `set_mech_param`.

    ek (mV): K+ reversal potential

    ena (mV): Na+ reversal potential

    eca (mV): Ca2+ reversal potential.

    Returns:

    cable: a new Section with all the properties and mechanisms.

    """
    cable = h.Section(name=name)
    cable.diam = diameter.to(ur.um).m
    cable.L = length.to(ur.um).m
    cable.cm = CM.to('uF/cm**2').m
    cable.Ra = RA.to('ohm*cm').m
    cable.nseg = nseg
    for mech in mechs:
        mech.insert_into(cable)
    if hasattr(cable, 'ek'):
        cable.ek = ek.to('mV').m
    if hasattr(cable, 'ena'):
        cable.ena = ena.to('mV').m
    if hasattr(cable, 'eca'):
        cable.eca = eca.to('mV').m
    if verbose:
        print('Created cable', name, 'with', nseg, 'segments')
        for x in cable:
            print(
                'Segment at', x.x, 'diam=', x.diam, 'area=', x.area(),
                'area computed=', np.pi * x.diam * cable.L / cable.nseg, 'ri=',
                x.ri(), 'computed ri=', 0.01 * cable.Ra *
                (cable.L / 2 / cable.nseg) / (np.pi * (x.diam / 2)**2))
            for mech in mechs:
                m = getattr(x, mech.name)
                print('  Has mechanism', m.name())
    sys.stdout.flush()
    return cable
    parser.add_argument(
        '--rec-by-region',
        action='store_true',
        help='record `reccount` sections in every region if possible',
        dest='recbyreg')

    return parser


if __name__ == '__main__':
    parser = make_parser()
    args = parser.parse_args()

    mechs = {
        'pas': {
            'g': 1.0 / Q_(args.RM, 'ohm*cm**2'),
            'e': Q_(args.Em, 'mV')
        }
    }
    h.xopen(args.celltemplate)
    ggn = nu.create_cell(args.cellname,
                         mechparams=mechs,
                         Ra=args.RA,
                         filename=args.celltemplate)
    g0 = nu.nrngraph(ggn)
    # for node in g0:
    #     print(node)
    # g, nmap = ng.renumber_nodes(g0, ggn.soma.name())
    reccount = args.reccount
    good_nodes = [n for n in g0.nodes() if g0.node[n]['orig'] is not None]
    ggn.geom_nseg()  # recompute the compartmentalization
Пример #10
0
    parser.add_argument(
        '--amp',
        type=float,
        dest='amp',
        nargs='+',
        default=[1e-2, 1e-1, 5e-3],
        help='The amplitude (in nA) of injected current, or three numbers'
        ' specifying the start, stop and increment')
    return parser


if __name__ == '__main__':
    args = make_parser().parse_args()
    logger.info('Command line: {}'.format(' '.join(sys.argv)))
    ggn_kc_syn_params = {
        'vmid': Q_('-40mV').to('mV').m,
        'vslope': Q_('5.0mV').to('mV').m,
        'e': Q_('-80mV').to('mV').m,
        'gbar': Q_('1e-3uS').to('uS').m,
        'tau': Q_('4.0ms').to('ms').m
    }
    # Note: I increased threshold to avoid transmission during low  frequency stimulus
    # where KC can have sustained depolarization.
    kc_ggn_syn_params = {
        'threshold': Q_('-10.0mV').to('mV').m,
        'delay': Q_('1.0ms').to('ms').m,
        'e': Q_('0.0mV').to('mV').m,
        'tau1': Q_('13.333ms').to('ms').m,
        'tau2': Q_('13.333ms').to('ms').m,
        'gmax': Q_('5pS').to('uS').m
    }
Пример #11
0
def main():
    parser = make_parser()
    args = parser.parse_args()
    logger.info('Command line args: {}'.format(str(sys.argv)))
    print(args.ggn_vm_file)
    # KCs with GGN inhibition
    inhibited_vec = defaultdict(list)
    solo_vec_list = []
    tstart = Q_(args.tstart).to('ms').m
    tend = Q_(args.tend).to('ms').m
    istart = Q_(args.istart).to('nA').m
    iend = Q_(args.iend).to('nA').m
    di = Q_(args.di).to('nA').m
    irange = np.arange(istart, iend + di / 2.0, di)
    logger.info('Starting current: {} nA'.format(istart))
    logger.info('End current: {} nA'.format(iend))
    logger.info('Increment: {} nA'.format(di))
    logger.info('current range: {}'.format(irange))
    ggn_vm = {}
    for input_file in args.ggn_vm_file:
        ggn_vm[input_file] = np.loadtxt(input_file)
    for inject in irange:
        for input_file, vm in ggn_vm.items():
            kc_vvec, ggn_gvec = make_kc_with_dynaclamp(args.kc, args.kc_file,
                                                       inject, tstart, tend,
                                                       vm)
            inhibited_vec[input_file].append((kc_vvec, ggn_gvec))
        # KC without any inhibition
        kc_vvec, ggn_gvec = make_kc_with_dynaclamp(args.kc, args.kc_file,
                                                   inject, tstart, tend)
        solo_vec_list.append(kc_vvec)
    tvec = h.Vector()
    tvec.record(h._ref_t)
    h.tstop = tend
    print('Init')
    h.init()
    print('Run')
    h.run()
    print('Finished simulation')
    fig, ax = plt.subplots(nrows=len(irange) + 1,
                           ncols=len(ggn_vm) + 1,
                           sharex='all',
                           sharey='all')
    t = np.array(tvec.x)
    solo_data = []
    for ii, vvec in enumerate(solo_vec_list):
        ax[ii + 1, 0].plot(tvec, vvec, color='#e66101')
        solo_data.append(np.array(vvec.x))
    combined = np.vstack(solo_data)

    prefix = 'UTC' + timestamp.strftime('%Y%m%d_%H%M%S')
    fname = '{}_solo_kc.npz'.format(prefix)
    np.savez(fname, t=t, vm=combined, inject=irange)
    logger.info('Saved solo KC data in {}'.format(fname))
    for jj, input_file in enumerate(args.ggn_vm_file):
        fname = '{}_{}.npz'.format(prefix, os.path.basename(input_file))
        data = []
        kc_vm_list = inhibited_vec[input_file]
        for ii, (vvec, gvec) in enumerate(kc_vm_list):
            data.append(np.array(vvec.x))
            ax[ii + 1, jj + 1].plot(tvec, vvec, color='#e66101')
            ax[ii + 1, 0].set_ylabel('{} pA'.format(irange[ii] * 1e3))
            # ax[ii+1, 0].set_ylabel('{} pA'.format(int(np.round(irange[ii]*1e3))))  # to avoid decimal point when integer values
        # ax[0, jj+1].plot(tvec, gvec)
        # ax[0, jj+1].plot(ggn_vm[input_file][:,0], ggn_vm[input_file][:,1])
        ax[0, jj + 1].set_title(input_file)
        combined = np.vstack(data)
        np.savez(fname,
                 combined=combined,
                 irange=irange,
                 ggn_vm=ggn_vm[input_file])
        logger.info(
            'Saved data from dynamic clamp with input from {} in {}'.format(
                input_file, fname))
    for axis in ax.flat:
        axis.set_xlim(250, 1750)
        fig.set_size_inches(210 / 25.4, 290 / 25.4)
    fig.tight_layout()
    fig.savefig('{}_KC_dynamic_range_with_ggn_vm.svg'.format(prefix))
    plt.show()
    print('End')
Пример #12
0
import argparse
import numpy as np
from collections import defaultdict
import matplotlib
matplotlib.use('Qt5Agg')
from matplotlib import pyplot as plt
import h5py as h5
from config import Q_, h, logger, timestamp, mypid, myjobid, nrn_version
from timeit import default_timer as timer
import ephys
import nrnutils as nu
import neurograph as ng
import nsdf

GGN_KC_SYN_PARAMS = {
    'vmid': Q_('-40mV').to('mV').m,
    'vslope': Q_('5.0mV').to('mV').m,
    'e': Q_('-80mV').to('mV').m,
    'gbar': Q_('1e-3uS').to('uS').m,
    'tau': Q_('4.0ms').to('ms').m
}

# keep global reference of created model components so that they are
# not garbage collected when out of scope
model_dict = {}


def make_kc_with_dynaclamp(kc_name,
                           kc_file,
                           inject,
                           tstart,