Exemplo n.º 1
0
def sim_slopes_debug(Cc_cells, cc_env, Dm_array, z_array, ion_i, gj_connects,
                     GP):
    sim.cc_cells = Cc_cells
    Vm = sim.compute_Vm(Cc_cells, GP)

    # General note: our units of flux are moles/(m2*s). The question: m2 of
    # what area? You might think that for, e.g., ion channels, it should be per
    # m2 of ion-channel area -- but it's not. All fluxes are per m2 of cell-
    # membrane area. Thus, the (e.g.,) diffusion rate through ion channels must
    # be scaled down by the fraction of membrane area occupied by channels.
    # The same goes for ion pumps and GJs.

    # Run the Na/K-ATPase ion pump in each cell.
    # Returns two 1D arrays[N_CELLS] of fluxes; units are moles/(m2*s)
    pump_Na, pump_K, _ = stb.pumpNaKATP(Cc_cells[ion_i['Na']],
                                        cc_env[ion_i['Na']],
                                        Cc_cells[ion_i['K']],
                                        cc_env[ion_i['K']], Vm, GP.T, GP, 1.0)

    # Kill the pumps on worm-interior cells (based on Dm=0 for all ions)
    keep_pumps = np.any(Dm_array > 0, 0)  # array[n_cells]
    pump_Na *= keep_pumps
    pump_K *= keep_pumps

    # for each ion: (sorted to be in order 0,1,2,... rather than random)
    GHK_fluxes = np.empty(Cc_cells.shape)
    for ion_name, ion_index in sorted(ion_i.items(),
                                      key=operator.itemgetter(1)):
        # GHK flux across membranes into the cell
        # It returns array[N_CELLS] of moles/(m2*s)
        f_ED = sim.GHK(ion_index, Vm)
        f_ED *= sim.eval_magic(sim.ion_magic[ion_index, :])
        GHK_fluxes[ion_index] = f_ED

    # Gap-junction computations.
    deltaV_GJ = (Vm[gj_connects['to']] - Vm[gj_connects['from']])  # [n_GJs]

    # Get the gap-junction Norton-equivalent circuits for all ions at once.
    # Units of Ith are mol/(m2*s); units of Gth are mol/(m2*s) per Volt.
    (GJ_Ith, GJ_Gth) = sim.GJ_norton(GP)  # Both are [n_ions,n_GJs].

    # As opposed so sim.slew_cc(), our callers just want GJ diffusion and
    # drift.
    # [n_ions,n_GJs] * [n_GJs]
    GJ_diff = GJ_Ith.copy() * sim.eval_magic(sim.GJ_magic)
    # [n_ions,n_GJs] * [n_GJs] * [n_GJs]
    GJ_drif = GJ_Gth * sim.eval_magic(sim.GJ_magic) * deltaV_GJ

    # Next, do generation and decay.
    gen = sim.gen_cells.copy()  # [n_ions, n_cells]
    decay = Cc_cells.copy()  # [n_ions, n_cells]
    for ion_name, ion_index in sorted(ion_i.items(),
                                      key=operator.itemgetter(1)):
        gen[ion_index] = sim.gen_cells[ion_index,:] \
                         * sim.eval_magic(sim.gen_magic[ion_index,:])
        decay[ion_index, :] *= sim.decay_rates[ion_index]

    # All returned values are in moles/(m2*s), where the m2 is m2 of
    # cell-membrane area.
    return (pump_Na, pump_K, GHK_fluxes, GJ_diff, GJ_drif, gen, decay)
Exemplo n.º 2
0
def dump(t, cc_cells, units, long):
    print('\nt={}: dumping {}-format...'.format(t,
                                                'long' if long else 'short'))

    # Print cc_cells[].
    sim.cc_cells = cc_cells
    np.set_printoptions(formatter={'float': '{:4.0f}'.format})
    print('cc_cells=')
    for ion_name, idx in sorted(sim.ion_i.items(), key=operator.itemgetter(1)):
        if (cc_cells[idx, :].sum() > 0):
            print('   {} {}'.format(cc_cells[idx], ion_name))

    # Print Vm.
    np.set_printoptions(formatter={'float': '{:4.2f}'.format})
    print('Vm =      {}mV'.format(sim.compute_Vm(cc_cells, sim.GP) * 1000.0))
    if (not long):
        return

    (pump_Na, pump_K, GHK_fluxes, GJ_diff, GJ_drif, gen, decay) \
      =sim_slopes_debug (cc_cells,sim.cc_env,sim.Dm_array,sim.z_array, \
                                  sim.ion_i,sim.gj_connects,sim.GP)
    (scl,
     tag) = scale([pump_Na, pump_K, GHK_fluxes, GJ_diff, GJ_drif, gen, decay],
                  units, sim.GP)

    # Get the GJ contributions to the flux in each cell.
    GJ_diff_by_cell = np.zeros(cc_cells.shape)
    GJ_drif_by_cell = np.zeros(cc_cells.shape)
    for ion in range(cc_cells.shape[0]):
        np.add.at(GJ_drif_by_cell[ion, :], sim.gj_connects['from'],
                  -GJ_drif[ion])
        np.add.at(GJ_drif_by_cell[ion, :], sim.gj_connects['to'], GJ_drif[ion])
        np.add.at(GJ_diff_by_cell[ion, :], sim.gj_connects['from'],
                  -GJ_diff[ion])
        np.add.at(GJ_diff_by_cell[ion, :], sim.gj_connects['to'], GJ_diff[ion])

    # For each ion, sum all the various contributions per cell.
    ion_totals = GHK_fluxes + GJ_diff_by_cell + GJ_drif_by_cell
    ion_totals[sim.ion_i['Na']] += pump_Na
    ion_totals[sim.ion_i['K']] += pump_K

    # And also get the grand total flux (all ions together, for QSS) per cell
    grand_totals = (ion_totals.T * sim.z_array).T.sum(0)

    # Now the summing & distributing is done; round to integers for printing.
    pump_Na = np.round(pump_Na * scl)
    pump_K = np.round(pump_K * scl)
    GHK_fluxes = np.round(GHK_fluxes * scl)
    GJ_diff = np.round(GJ_diff * scl)
    GJ_drif = np.round(GJ_drif * scl)
    GJ_diff_by_cell = np.round(GJ_diff_by_cell * scl)
    GJ_drif_by_cell = np.round(GJ_drif_by_cell * scl)
    gen = np.round(gen * scl)
    decay = np.round(decay * scl)
    ion_totals = np.round(ion_totals * scl)
    grand_totals = np.round(grand_totals * scl)

    # First, ion channels and pumps
    np.set_printoptions(formatter={'float': '{:4.0f}'.format})
    for ion_name, ion_idx in sorted(sim.ion_i.items(),
                                    key=operator.itemgetter(1)):
        if ((GHK_fluxes[ion_idx, :] != 0).any()):
            print('{:2s} ionCh: {} {}'.format(ion_name, GHK_fluxes[ion_idx],
                                              tag))
        if (ion_name == 'Na'):
            print('Na pump:  {} {}'.format(pump_Na, tag))
        if (ion_name == 'K'):
            print('K  pump:  {} {}'.format(pump_K, tag))

        if ((GJ_diff_by_cell[ion_idx, :] != 0).any()):
            print('{:2s} GJdiff:{} {}'.format(ion_name,
                                              GJ_diff_by_cell[ion_idx], tag))
        if ((GJ_drif_by_cell[ion_idx, :] != 0).any()):
            print('{:2s} GJdrif:{} {}'.format(ion_name,
                                              GJ_drif_by_cell[ion_idx], tag))
    # Per-ion totals
    print('\nTotals by ion from all sources:')
    for ion_name, ion_idx in sorted(sim.ion_i.items(),
                                    key=operator.itemgetter(1)):
        if ((ion_totals[ion_idx, :] != 0).any()):
            print('{:2s} total: {} {}'.format(ion_name, ion_totals[ion_idx],
                                              tag))

    # Grand totals
    print('\nGrand valence-weighted totals from all sources across all ions:')
    print('          {} {}'.format(grand_totals, tag))

    # Now, GJs. We did them above by cell; this time, by GJ
    print('\nnow the GJs by GJ (if any have non-zero flux):')
    for ion_name, ion_idx in sorted(sim.ion_i.items(),
                                    key=operator.itemgetter(1)):
        if ((GJ_diff[ion_idx, :] != 0).any()):
            print('{:2s} GJ diff: {} {}'.format(ion_name, GJ_diff[ion_idx],
                                                tag))
        if ((GJ_drif[ion_idx, :] != 0).any()):
            print('{:2s} GJ drif: {} {}'.format(ion_name, GJ_drif[ion_idx],
                                                tag))

    # Generation and decay
    if ((gen != 0).any() or (decay != 0).any()):
        print('\nnow generation and decay:')
    for ion_name, ion_idx in sorted(sim.ion_i.items(),
                                    key=operator.itemgetter(1)):
        if ((gen[ion_idx, :] != 0).any()):
            print('{:2s} generation: {} {}'.format(ion_name, gen[ion_idx],
                                                   tag))
        if ((decay[ion_idx, :] != 0).any()):
            print('{:2s} decay: {} {}'.format(ion_name, decay[ion_idx], tag))
Exemplo n.º 3
0
def setup_and_sim(worm, time_to_run):
    import sys
    """
    # If no command-line arguments are given, prompt for them.
    if (len (sys.argv) <= 1):
        args = 'main.py ' + input('Arguments: ')
        sys.argv = re.split (' ', args)
    regress_mode = (len(sys.argv) == 4) and (sys.argv[3]=="--regress")
    if (regress_mode):
        sys.argv = sys.argv[0:3]
    if (len(sys.argv) != 3):
       raise SyntaxError('Usage: python3 main.py test-name-to-run sim-end-time')
    """
    end_time = time_to_run

    # Run whatever test got chosen on the command line.
    GP = sim.Params()
    setup_lab_worm(GP, worm)
    #eval ('setup_'+sys.argv[1]+'(GP)')

    #if (regress_mode): # Works even if setup_...() overrules these params!
    #    GP.adaptive_timestep = False   # Force regression
    #    GP.sim_dump_interval = 1
    #    GP.sim_long_dump_interval = 10

    # Initialize Vmem -- typically 0, or close to that.
    Vm = sim.compute_Vm (sim.cc_cells, GP)
    assert (Vm<.5).all()    # I.e.,roughly charge neutral
    np.set_printoptions (formatter={'float': '{: 6.3g}'.format}, linewidth=90)
    #print ('Initial Vm   ={}mV\n'.format(1000*Vm))

    #print ('Starting main simulation loop')
    t_shots, cc_shots = sim.sim (end_time, GP)
    #print ('Simulation is finished.')

    # Now, the simulation is over. Do any end-of-sim analysis.
    #edb.analyze_equiv_network (GP)

    # If your network contains cells that are interconnected by GJs, then
    # pretty_plot() can make a nice picture of the interconnections and each
    # cell's Vm.
    Vm = sim.compute_Vm (sim.cc_cells, GP)
    # print("Worm Fitness = " + str(worm.fitness))
    # print("Km = " + str(worm.Km))
    # print("N = " + str(worm.N))
    # print("Gj_scale = " + str(worm.Gj_scale))
    # print("num_cells = " + str(worm.num_cells))
    # print("G_k = " + str(worm.G_k))
    # print("G_k = " + str(worm.G_na))
    # print("G_cl = " + str(worm.G_cl))
    # print("Gj_diff_m = " + str(worm.Gj_diff_m))

    #print("Vmem?: {}".format(Vm))
    Vgrad = abs(Vm[0] - Vm[worm.num_cells -1])
    worm.grad_stren = Vgrad
    #eplt.pretty_plot (Vm*1e3)

    # We often want a printed dump of the final simulation results.
    np.set_printoptions (formatter={'float': '{:.6g}'.format}, linewidth=90)
    #edb.dump (end_time, sim.cc_cells, edb.Units.mV_per_s, True)
    #edb.dump (end_time, sim.cc_cells, edb.Units.mol_per_m2s, True)

    # We often want graphs of various quantities vs. time.
    # If so, then comment out the quit() here, and then modify the code below
    # as desired.
    # quit()
    Na = sim.ion_i['Na']; K = sim.ion_i['K']; Cl=sim.ion_i['Cl']
    # P=sim.ion_i['P']; M=sim.ion_i['M']
    Vm_shots = [sim.compute_Vm (c,GP)*1000 for c in cc_shots]
    n_cells = sim.cc_cells.shape[1]
    # eplt.plot_Vmem_graph(t_shots,Vm_shots, np.arange(n_cells),'Vmem(mV)')
    # eplt.plot_Vmem_graph(t_shots,[s[Na] for s in cc_shots],np.arange(n_cells),'[Na] (mol/m3')
    # eplt.plot_Vmem_graph(t_shots,[s[K]  for s in cc_shots],np.arange(n_cells),'[K] (mol/m3')
    # eplt.plot_Vmem_graph(t_shots,[s[Cl]  for s in cc_shots],np.arange(n_cells),'[Cl] (mol/m3')
    #eplt.plot_Vmem_graph(t_shots,[s[M] for s in cc_shots],np.arange(n_cells),'[M] (mol/m3')
Exemplo n.º 4
0
def analyze_equiv_network(GP):
    print('Analyze_equiv_network() info...')

    # First, the ion-channel equivalents. And x1000 to use mV and not V.
    Vn = Vnernst(GP) * 1000  # 3 rows(for Na,K,Cl) x num_cells
    Gthev = IC_Gthev(GP) / 1000  # 3 rows x num_cells

    (Vthev_net, Gthev_net) = merge_Thev(Vn, Gthev,
                                        sim.z_array)  # merge across ions

    # Actual fluxes at current Vm
    Vm = sim.compute_Vm(sim.cc_cells, sim.GP) * 1000
    IC_net = (Vm - Vn) * Gthev  # 3 rows x num_cells
    allIC_net = (Vm -
                 Vthev_net) * Gthev_net  # summed across all ions-> [num_cells]

    # Make the ion-channel equivalents pretty for printout.
    units = Units.mol_per_m2s
    (scl, tag) = scale([Gthev, Gthev_net], units, GP)
    Gthev = np.round(Gthev * scl)
    Gthev_net = np.round(Gthev_net * scl)
    IC_net = np.round(IC_net * scl)  # 3 rows x num_cells
    allIC_net = np.round(allIC_net * scl)  # [num_cells]

    # Print out Vn, Gth for each ion channel.
    for ion_index, ion in enumerate(['Na', 'K', 'Cl']):
        np.set_printoptions(formatter={'float': '{:4.2g}'.format})
        print('    {:2s} IC Vn ={}mV'.format(ion, Vn[ion_index]))
        np.set_printoptions(formatter={'float': '{:4.0f}'.format})
        print('    {:2s} IC Gth={}{}'.format(ion, Gthev[ion_index],
                                             tag + '/mV'))
        print('    {:2s} IC net={}{}{}'.format(ion, IC_net[ion_index], tag,
                                               ' of ions through ICs'))

    # Print out Vn, Gth for the merged-across-all-ion-channels version.
    np.set_printoptions(formatter={'float': '{:4.2g}'.format})
    print('IC Vthev_net ={}mV'.format(Vthev_net))
    np.set_printoptions(formatter={'float': '{:4.0f}'.format})
    print('IC Gth_net   ={}{}'.format(Gthev_net, tag + '/mV'))
    print('IC net_net   ={}{}{}'.format(allIC_net, tag,
                                        ' of charge through ICs'))

    # Compute the QSS Vmem using this model, but taking the pumps into account,
    # and disregarding GJs.
    # We have (Vmem-Vthev_net)*Gthev_net + pump_Na + pump_K = 0, or
    # Vmem*Gthev_net - Vthev_net*Gthev_net + pump_Na + pump_K = 0, or
    # Vmem = (Vthev_net*Gthev_net + pump_Na + pump_K) / Gthev_net
    (pump_Na, pump_K, GHK_fluxes, GJ_diff, GJ_drif, gen, decay) \
      =sim_slopes_debug (sim.cc_cells,sim.cc_env,sim.Dm_array,sim.z_array, \
                                  sim.ion_i,sim.gj_connects,sim.GP)
    Vmem = (Vthev_net * Gthev_net + pump_Na + pump_K) / Gthev_net
    print('Open-circuit Vmem including pumps = ', Vmem)

    # Next, equivalents for GJs (if there are any).
    (GJ_Ith, GJ_Gth) = sim.GJ_norton(GP)
    if (GJ_Gth.size == 0):
        return

    # Scale the GJ models for printing.
    units = Units.mol_per_m2s
    units = Units.mV_per_s
    (scl, tag) = scale([GJ_Gth, GJ_Ith], units, GP)
    GJ_Gth = np.round(GJ_Gth * scl)
    GJ_Ith = np.round(GJ_Ith * scl)

    # Print the per-ion GJ models.
    for ion, ion_index in sorted(sim.ion_i.items(),
                                 key=operator.itemgetter(1)):
        if ((GJ_Ith[ion_index, :] != 0).any()):
            print('    {:2} GJ Ith   =  {}{}'.format(ion, GJ_Ith[ion_index],
                                                     tag))
        if ((GJ_Gth[ion_index, :] != 0).any()):
            print('    {:2} GJ Gth   =  {}{}'.format(ion, GJ_Gth[ion_index],
                                                     tag + '/V'))
Exemplo n.º 5
0
def plot_Vmem(t_shots, cc_shots, cells=None):
    Vm_shots = [sim.compute_Vm(c, sim.GP) * 1000 for c in cc_shots]
    n_cells = cc_shots[0].shape[1]
    cells = (np.arange(n_cells) if cells == None else np.array((cells)))
    plot_Vmem_graph(t_shots, Vm_shots, cells, 'Vmem(mV)')