Пример #1
0
def compare_weights(filename, param_list=None):
    """Run Simulations with different strengths of synapses (keeping the actual number from load_config the same.
    """
    if param_list:
        # keep param_list a list, but make first (only) arg a dict
        weights_dict = param_list[0]
        assert weights_dict['inh_weights']
        assert weights_dict['exc_weights']
    else:
        weights_dict = {
            'exc_weights': [10],
            'inh_weights': [10]
            }
    print("weight_dict:{}".format(weights_dict))
    load_file(filename)
    # load config
    load_config()
    # define hoc-accessible Vectors (lists)
    h("objref inhibWeights_config,exciteWeights_config")
    # convert python lists to NEURON Vectors
    h.inhibWeights_config = h.Vector(weights_dict['inh_weights'])
    h.exciteWeights_config = h.Vector(weights_dict['exc_weights'])
    # assign weight vectors during configWeights (which is called from (if not persistent synapses)
    # run.hoc > doRun() > loadParameters() > protocolStimVectors() > [proximal|distal]HzConfig > configWeights()
    h("""
        proc configWeights(){
            print "configWeights custom Python"
            inhibWeights = inhibWeights_config
            exciteWeights = exciteWeights_config
        }
    """)

    # iterating over weights is already done in run.hoc
    save_run("{}".format(filename))
Пример #2
0
def compare_synapses(filename, param_list=None, errors=0):
    """Run simulations with different number of (E,I) synapses"""
    if type(param_list) is tuple:
        skip, syn_list = param_list
    else:
        syn_list = param_list
        skip = SKIP_IF_EXISTS
    if not syn_list:
        syn_list = [(120, 10), (140, 50), (180, 130)]
    print("syn_list:{}".format(syn_list))
    load_file(filename)
    load_file(filename)
    vm, cli = get_base_vm_cli(filename)
    h.v_init = vm
    for i, (exc, inh) in enumerate(syn_list):
        h.newSynapses(exc, inh)
        try:
            save_run("{}_{},{}".format(filename, exc, inh), set_cli=cli, skip_if_exists=skip)
        except RuntimeError as re:
            print("Error {} occured on E={} & I={}".format(re, exc, inh))
            print("leftover params = {}".format(syn_list[i:]))
            if errors == 2:
                print("second time error occured, bailing")
                import sys
                sys.exit(-1)
            else:
                compare_synapses(filename, param_list=syn_list[i:], errors=errors + 1)
Пример #3
0
def compare_pkcc2_homo(filename, param_list=None):
    """Change homogeneity of KCC2 pump strength"""
    axon_pkcc2_list = [1]
    ldend_pkcc2_list = [0.5, 1, 2, 4]
    if param_list is not None:
        if np.iterable(param_list[0]) and type(param_list[0]) is not str:
            ldend_pkcc2_list, axon_pkcc2_list = param_list
        else:
            ldend_pkcc2_list = param_list
    base = 1.9297e-5
    print("ldend_pkcc2_list:{}".format(ldend_pkcc2_list))
    load_file(filename)

    if "KCC2" not in filename:
        # run a single simulation without KCC2.
        savename = "{}_({:.2f},{:.2f})".format(filename, 0, 0)
        save_run(savename)
        return

    cmd_bdend = "bdend.Pa_KCC2 = {}".format(base)
    h(cmd_bdend)
    for pkcc2 in ldend_pkcc2_list:
        cmd = "ldend.Pa_KCC2 = {}".format(base*pkcc2)
        print(cmd)
        h(cmd)
        for axon_pkcc2 in axon_pkcc2_list:
            axon_cmd = "axon.Pa_KCC2 = {}".format(base*axon_pkcc2)
            print(axon_cmd)
            h(axon_cmd)
            save_run("{}_({:.2f},{:.2f})".format(filename, pkcc2, axon_pkcc2))
Пример #4
0
def synapses_vs_weights(filename="distal", param_list=None):
    """Clump synapses and vary synapse numbers and synapse weights.

    param_list contains tuples of (exc_syn, inh_syn, exc_weight, inh_weight, clump)

    """
    import itertools
    syn_list = param_list
    if not syn_list:
        syn_list = itertools.product([1, 10, 100], [1, 10, 100],  # E, I synapse numbers
                                     [1, 5, 10], [1, 5, 10],  # E, I synapse weights
                                     [1, 10, 100]  # clumping
                                     )
        syn_list = [(10, 10, 1, 1, 10), (10, 10, 5, 5, 10), (10, 10, 10, 20, 10),
                    (10, 100, 18, 6, 10),
                    (10, 10, 18, 60, 10), (10, 10*100, 18, 6, 10), (10, 10, 18, 6*100, 10)]
    load_file(filename)
    icl_rec_vec = h.Vector()
    icl_rec_vec.record(h.ldend(0.5)._ref_icl)
    h.tstop = 500
    h("forall{cli=4.25}")
    h.hoc_stdout("synapses_vs_weights.txt")
    base_gmax = 0.00005  # uS
    inh_hz = 10
    for gmax_weight in [False]:
        print("gmax_weight: {} ".format(gmax_weight))
        for (i, (exc, inh, exc_weight, inh_weight, clump)) in enumerate(syn_list):
            h.newSynapses(exc, inh)
            h.clumpSynapses(clump)
            print("clumped")
            g_rec_vec_list = list()
            for g in range(int(h.ninh)):
                g_rec_vec = h.Vector()
                g_rec_vec.record(h.GABAa[g]._ref_g)
                g_rec_vec_list.append(g_rec_vec)

            h.exHz(10000, 1, exc_weight)
            if gmax_weight:
                h.inHz(inh_hz, 1, 1)
                h.gmax_GABAa = base_gmax*inh_weight
            else:
                h.inHz(inh_hz, 1, inh_weight)
            print(syn_list[i])
            icl_mean = []
            icl_stdev = []
            spikes_mean = []
            g_total_mean = []
            for k in range(5):
                h.run()
                icl_mean.append(icl_rec_vec.mean()*1e6)
                icl_stdev.append(icl_rec_vec.stdev()*1e6)
                spikes_mean.append(h.apc.n)
                total_g = 0
                for g_rec_vec in g_rec_vec_list:
                    total_g += g_rec_vec.mean()
                g_total_mean.append(total_g)
            print("icl_mean: \tmean:\t {} \tstd:\t {}".format(np.mean(icl_mean), np.std(icl_mean)))
            print("icl_stdev: \tmean:\t {} \tstd:\t {}".format(np.mean(icl_stdev), np.std(icl_stdev)))
            print("g total: \tmean:\t {} \tstd:\t {}".format(np.mean(g_total_mean), np.std(g_total_mean)))
            print("spikes: \tmean:\t {} \tstd:\t {}".format(np.mean(spikes_mean), np.std(spikes_mean)))
Пример #5
0
def compare_diam(filename, param_list=None):
    """Change distal dendrite's diameter"""
    diam_list = param_list
    if not diam_list:
        diam_list = [0.5, 1, 1.5, 2]
    print("diam_list:{}".format(diam_list))
    load_file(filename)
    for diam in diam_list:
        h("""ldend.diam = {}""".format(diam))
        save_run("{}_{}".format(filename, diam))
Пример #6
0
def compare_pCl(filename, param_list=None):
    """Change leak chloride permeability (ratio to leak potassium conductance)"""
    pcl_list = param_list
    if not pcl_list:
        pcl_list = [0.1, 0.4, 0.8, 1.2]
    print("pcl_list:{}".format(pcl_list))
    load_file(filename)
    # list of (exc,inh) synapses numbers
    for pcl in pcl_list:
        h.changePCl(pcl)
        save_run("{}_{}".format(filename, pcl))
Пример #7
0
def compare_dynamic_K(filename, param_list=None):
    """Run simulations with dynamic potassium (True) or not (False)
    The base filename should be used (e.g. 'distal') such that
    - distal is the baseline
    - distal_KCC2_True is KCC2 WITH dynamic potassium and
    - distal_KCC2_False is KCC2 WITHOUT dynamic potassium
    """
    if 'KCC2' in filename:
        print("ignoring {} in 'compare_dynamic_K' because param_list should cover this case".format(filename))
        return
    K_list = param_list
    if not K_list:
        K_list = ['control', True, False]
    print("K_list:{}".format(K_list))

    for dyn_K in K_list:
        fname = filename if dyn_K == 'control' else filename + "_KCC2"
        assert (dyn_K != 'control' and 'KCC2' in fname) or (dyn_K == 'control' and 'KCC2' not in fname)
        load_file(fname)
        # get steady state here as it isn't done in run.hoc anymore with the set_cli arg
        vm, cli = get_base_vm_cli(fname, compartment=h.ldend)
        h.v_init = vm
        if dyn_K == 'control':
            print("control (no KCC2 nor KCC2_pot")
            cmd = "forall{" + """
                              cli={cli}
                              cli0_cl_ion={cli}
                           """.format(cli=cli) +\
                  "}"
            h(cmd)
            save_run("{}_{}".format(fname, 0), set_cli=cli)
            pot = ""
        elif dyn_K:
            # then add KCC2 potassium
            cmd = """forall{
                uninsert pasghk
                uninsert KCC2
                insert pas
                insert KCC2_pot
                g_pas = 0.00021
                }"""
            h(cmd)
            pot = "_pot"
        else:
            # already have KCC2 in the neuron
            pot = ""
        cmd = "forall{" + """
                  cli={cli}
                  cli0_cl_ion={cli}
                  cli0_KCC2{pot}={cli}
               """.format(cli=cli, pot=pot) +\
              "}"
        h(cmd)
        save_run("{}_{}".format(fname, int(dyn_K)), set_cli=cli)
Пример #8
0
def compare_duration(filename, param_list=None):
    """Change tstop to compare"""
    tstop_list = param_list
    if not tstop_list:
        base = h.tstop_config
        tstop_list = [base/10, base/2, base, base*2, base*10]
    print("tstop_list:{}".format(tstop_list))
    load_file(filename)
    for tstop in tstop_list:
        h.tstop_config = tstop  # doRun() calles loadParameters() in run.hoc which retrieves config variables
        h.tstop = tstop  # we set this here anyway
        save_run("{}_{}".format(filename, tstop))
Пример #9
0
def compare_synapses_clumped(filename, param_list=None):
    """Run simulations with synapses located close together. Clumping implemented in `methods.hoc`
    """
    syn_list = param_list
    if not syn_list:
        syn_list = [(120, 10), (140, 50), (180, 130)]
    print("syn_list:{}".format(syn_list))
    load_file(filename)
    for (exc, inh, clump) in syn_list:
        h.newSynapses(exc, inh)
        h.clumpSynapses(clump)
        save_run("{}_{},{}".format(filename, exc, inh))
Пример #10
0
def just_run(filename, param_list=None):
    """
    Proxy for save_run, that accepts a param_list as expected in `nrnpy.start`
    """
    load_file(filename)
    if param_list is not None:
        if type(param_list) is str:
            h(param_list)
        elif type(param_list[0]) is str:
            for cmd in param_list:
                h(cmd)
    save_run(filename)
Пример #11
0
def compare_pkcc2(filename, param_list=None):
    """Change pump-strength of KCC2"""
    pkcc2_list = param_list
    if not pkcc2_list:
        base = 1.9297e-5  # default value from mod file
        pkcc2_list = [base/2, base, base*2, base*4]
    print("pkcc2_list:{}".format(pkcc2_list))
    load_file(filename)
    for pkcc2 in pkcc2_list:
        cmd = "forall{" +\
              "Pa_KCC2 = {}".format(pkcc2) +\
              "}"
        h(cmd)
        save_run("{}_{}".format(filename, pkcc2))
Пример #12
0
def compare_synapse_types(filename, param_list=None):
    """Run simulations with different synapse types. Note that the strength of these synapses will be wildy off.

    * 0 - frequency-based ('f-in') synapses (receives input via NETSTIM)
    * 1 - fluctuating conductance 'gclamp' synapses
    * 2 - exc is 'f-in', inh is 'gclamp'
    * 3 - inh is 'f-in', exc is 'gclamp'
    """
    syn_type_list = param_list
    if not syn_type_list:
        syn_type_list = [0, 1, 2, 3]
    print("syn_type_list:{}".format(syn_type_list))
    load_file(filename)
    for type_num in syn_type_list:
        h.changeSynapseType(type_num)
        save_run("{}_{}".format(filename, type_num))
Пример #13
0
def compare_cli(filename, param_list=None):
    """Change internal chloride concentration (for constant/static) runs"""
    cli_list = param_list
    if not cli_list:
        cli_list = [2.5, 5, 7.5, 10, 12.5, 15, 20, 25, 30]
    print("cli_list:{}".format(cli_list))
    load_file(filename)
    for cli in cli_list:
        # chloride is set inside run.hoc through save_run --> doRun(set_cli)
        cmd = "forall{" + """
                          cli={cli}
                          cli0_cl_ion={cli}
                          cli0_KCC2={cli}
                       """.format(cli=cli) +\
              "}"
        h(cmd)
        save_run("{}_{}".format(filename, cli), set_cli=cli)
Пример #14
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))
Пример #15
0
def check_num_synapses(f, synapse_type, exc_weight, inh_weight,
                       exc_syn_list=None, inh_syn_list=None,
                       exc_freq=5, inh_freq=5,
                       exc_noise=1, inh_noise=1,
                       num_runs=5, max_num_runs=15,
                       upper_bound=15):
    """

    A target of 5 Hz is used, with simulations with 4, 5, and 6 spikes taking extra trials. This target and the
    range to expand the number of trials can be implemented relatively easily in the future.

    Assumptions
    - GABAa gmax per synapse = 350 pS
    - AMPA+NMDA gmax per synapse = 1000 pS [AMPA:NMDA ratio = 1]

    :param f: file handle to write results
    :type f: TextIO
    """
    step = 10
    if inh_syn_list is None:
        inh_syn_list = range(0, 800 + step, step)
    if exc_syn_list is None:
        exc_syn_list = range(0, 800 + step, step)
    if upper_bound is not None:
        assert upper_bound > 0
    else:
        upper_bound = 10000

    prev_run = f.read()

    load_file(synapse_type)

    h.tstop = 1000
    h.useCV()

    # without a 2nd load NEURON seems to complain about synapseFile being a non-variable...
    load_file(synapse_type)

    for inh_syn in inh_syn_list:
        above_bound = False
        for exc_syn in exc_syn_list:
            line = "exc_syn: {} ({})\t inh_syn: {} ({})\n".format(exc_syn, exc_weight, inh_syn, inh_weight)
            if line in prev_run:
                continue
            f.write(line)
            logger.info(line)
            if above_bound:
                # skip values of excitation when firing rate is already above
                # 15 Hz for lower values of excitation
                f.write("\n{} +- {} (n={})\n".format(16, 0, 0))
                logger.info("{} +- {} (n={})\n".format(16, 0, 0))
            else:
                # newSynapses from methods.hoc
                h.newSynapses(exc_syn, inh_syn)
                # Frequency, Noise, Weight (# synapses)
                h.inPy(inh_freq, inh_noise, inh_weight)
                h.ex(exc_freq, exc_noise, exc_weight)
                x = []
                f.write("spikes:\n")
                num_zero = 0
                run_list = list(range(num_runs))
                for run in run_list:
                    h.run()
                    x.append(h.apc.n)
                    f.write("\t {}".format(h.apc.n))
                    logger.info("\t spikes {}".format(h.apc.n))
                    if h.apc.n == 0:
                        num_zero += 1
                        if num_zero >= num_runs/2:
                            logger.info("break from too many 0's")
                            f.write("break from too many 0's")
                            break
                    elif (4 <= h.apc.n <= 6) and len(run_list) < max_num_runs:
                        # get more accurate results for values close to 5
                        run_list.append(len(run_list))
                    elif h.apc.n > upper_bound:
                        logger.info("break from above {}".format(upper_bound))
                        f.write("break from above {}".format(upper_bound))
                        above_bound = True
                        break
                mean = np.mean(x)
                std = np.std(x)
                f.write("\n{} +- {} (n={})\n".format(mean, std, run + 1))
                logger.info("{} +- {} (n={})\n".format(mean, std, run + 1))
def load_config():
    """Base configuration method."""
    load_file("config.hoc", set_file_name=False, force_reload=False)
Пример #17
0
def pyrun(file_name,
          synapse_type=1,
          synapse_numbers=(100, 100),
          syn_input=None,
          diam=None,
          pa_kcc2=None,
          location='axon',
          trials=1,
          save=True,
          tstop=TSTOP,
          **kwargs):
    """
    Run a NEURON simulation for a neuron specified in ``file_name`` with input specified by other parameters provided.

    :param file_name: Neuron definition (excluding '.hoc').
    :type file_name: str
    :param synapse_type: Type of synapses to use (0 for frequency-based 'f-in', 1 for persistent conductance, 'gclamp').
    :type synapse_type: int
    :param synapse_numbers: Number of (E, I) on the neuron.
    :type synapse_numbers: (int, int)
    :param syn_input: Mapping of excitatory/inhibitory type to input strength. {'ex', E, 'in: I}
    :type syn_input: dict[str, int]
    :param diam: Re-specify diam for specific regions of the neuron. Valid: 'ldend', 'bdend', 'soma', 'axon'.
    :type diam: dict[str: float]
    :param pa_kcc2: Strength of KCC2.
    :type pa_kcc2: float
    :param location: Location to recording firing rate.
    :type location: str
    :param trials: Number of repeated simulations to run.
    :type trials: int
    :param save: Whether to load/save the results from/to file.
    :type save: bool
    :param tstop: Length of simulation (ms).
    :type tstop: float
    :param kwargs: Other keywords are ignored.

    :return: Pair of DataFrame with results and name of save file (even if not saved, the name is generated).
    :rtype: (pd.DataFrame, str)
    """
    if syn_input is None:
        syn_input = {'in': 5, 'ex': 5}
    save_name = "{}_{}_{}_{}".format(file_name, synapse_type, synapse_numbers,
                                     syn_input)
    save_name += "_{}".format(diam) if diam is not None else ''
    save_name += "_{}".format(pa_kcc2) if pa_kcc2 is not None else ''
    save_name += "_{}_{}".format(location, trials)
    save_name = save_name.replace(" ", "").replace("'", "").replace(
        ":", "=").replace("{", "(").replace("}", ")")
    logger.info(save_name)
    if save:
        loaded = load_from_file(save_name)
        if loaded is not None:
            return loaded, save_name

    load_file(file_name)
    load_file(file_name)
    if diam is not None:
        for seg in diam.keys():
            nrn_seg = get_compartment(seg)
            nrn_seg.diam = diam[seg]
    if pa_kcc2 is not None:
        hoc_cmd = "forall {" + """
            Pa_KCC2 = {pa_kcc2}e-5""".format(pa_kcc2=pa_kcc2) +\
                  " }"
        h(hoc_cmd)
    compartment = get_compartment(location)
    if file_name.find('distal') > -1:
        cli_rec_loc = get_compartment('ldend')
    elif file_name.find('proximal') > -1 or file_name.find('proximal') > -1:
        cli_rec_loc = get_compartment('bdend')
    else:
        cli_rec_loc = get_compartment('soma')

    logger.info("recording cli from {}".format(cli_rec_loc.hname()))

    h("access {}".format(location))
    h.changeSynapseType(synapse_type)
    h.newSynapses(synapse_numbers[0], synapse_numbers[1])
    h.inPy(0)
    h.ex(0)
    vm_init, cli = get_base_vm_cli(file_name, compartment=compartment)
    h.v_init = vm_init
    h_str = """
        forall{""" + """
            cli = {0}
            cli0_cl_ion = {0}
            """.format(cli)
    if file_name.find("KCC2") > 0:
        h_str += """cli0_KCC2 = {0}
        """.format(cli)
    h_str += "}"
    h(h_str)

    h.tstop = tstop

    if synapse_type == 0:
        # Hz, duration (s), start (ms), noise, weight/channels
        h.inPy(syn_input['in'], h.tstop / 1000, 0, 1, 1)
        h.ex(syn_input['ex'], h.tstop / 1000, 0, 1, 1)
    else:
        h.inPy(syn_input['in'])
        h.ex(syn_input['ex'])

    # create recording vector objects
    t_rec = h.Vector()
    v_rec = h.Vector()
    cli_rec = h.Vector()
    spike_rec = h.Vector()

    t_rec.record(h._ref_t)
    v_rec.record(compartment(0.5)._ref_v)
    cli_rec.record(cli_rec_loc(0.5)._ref_cli)
    spike_rec.record(h.apc._ref_n)

    time_past = current_time('ms')
    logger.info("using {}...".format(file_name))
    assert trials > 0
    logger.info(save_name)
    logger.info("trial # | # spikes")
    df = pd.DataFrame()
    for i in range(trials):
        trial_num = i + 1
        h.run()
        logger.info("{:7} | {:8}".format(trial_num, h.apc.n))

        temp_dict = {
            (trial_num, 'v'): v_rec.as_numpy(),
            (trial_num, 'cli'): cli_rec.as_numpy(),
            (trial_num, 'spikes'): spike_rec.as_numpy()
        }
        recording = pd.DataFrame(temp_dict, index=t_rec.to_python())

        df = pd.concat([df, recording], axis=1)

    logger.info("time taken: {}ms".format(current_time('ms') - time_past))

    if save:
        save_to_file(save_name, df)
    return df, save_name
def get_trace(file_name,
              synapse_type=0,
              synapse_numbers=(10, 10),
              hz=None,
              space_plot=False,
              vm=-65.0,
              cli=5.0,
              ldend_diam=0.5):
    """
    Get the voltage trace and cli trace from running a hoc file.

    Optionally, specify space_plot to get the cli along the entire neuron (nseg dependent).

    `vm` and `cli` should be specified by running `get_base_vm_cli` beforehand and passing in those values.

    :param file_name: hoc-specified neuron to load (from hoc_files/cells)
    :type file_name: str
    :param synapse_type: 0 if 'f-in' NETSTIM synapses. 1 if 'persistetnt' fluctuating conductance synapses.
    :type synapse_type: int
    :param synapse_numbers: Number of (E,I) synapses.
    :type synapse_numbers: tuple of int
    :param hz: Input to the synapses. Keys used are 'in' and 'ex'.
        Either frequency-based (`synapse_type` is `0`) or relative conductance (`synapse_type` is `1`).
    :type hz: dict of str
    :param space_plot: Compute cli at every location.
    :type space_plot: bool
    :param vm: Initial membrane potential
    :type vm: float
    :param cli: Initial chloride ion concentration
    :type cli: float
    :param ldend_diam: Diameter of distal dendrite.
    :type ldend_diam: float
    :return: Time array, voltage array, chloride array,
        space plot dict data of form `{distance from soma: chloride array}`
    :rtype: tuple[h.Vector, h.Vector, h.Vector, dict of float:h.Vector]
    """
    if hz is None:
        hz = {'in': 5, 'ex': 5}
    load_file(file_name)

    h.changeSynapseType(synapse_type)
    h.newSynapses(synapse_numbers[0], synapse_numbers[1])
    if synapse_type == 0:
        h.inPy(hz['in'], 1, 1)
        h.ex(hz['ex'], 1, 1)
    else:
        h.inPy(hz['in'])
        h.ex(hz['ex'])
    if "distal" in file_name:
        compartment = h.ldend
    elif "proximal" in file_name:
        compartment = h.bdend
    else:
        compartment = h.soma

    h("forall {" + "cli={} ".format(cli) + "cli0_KCC2={}".format(cli) + "}")
    for sec in h.allsec:
        for seg in sec:
            seg.cli = cli
    h.cli0_cl_ion = cli
    h.ldend.diam = ldend_diam
    # sort on key
    data = {}
    if space_plot:
        h.distance(0, 1, sec=h.soma)
        for sec in h.allsec:
            for seg in sec:
                # label = f"{sec.name()}({seg.x:.5f})"
                label = h.distance(seg.x, sec=sec)
                if 'dend' in sec.name():
                    label *= -1
                data[label] = h.Vector()
                data[label].record(sec(seg.x)._ref_cli)

    h.tstop = 1000.0
    time_past = current_time('ms')
    logger.info("running {}...".format(file_name))
    h.v_init = vm
    h.finitialize(vm)
    t_vec = h.Vector()
    t_vec.record(h._ref_t)
    v_vec = h.Vector()
    v_vec.record(h.axon(0.5)._ref_v)
    cli_vec = h.Vector()
    cli_vec.record(compartment(0.5)._ref_cli)

    h.run()

    logger.info("time taken: {}ms".format(current_time('ms') - time_past))
    logger.info("no. spikes = {}".format(h.apc.n))

    return t_vec, v_vec, cli_vec, data