Source code for netpyne.sim.run

"""
Module for running simulations

"""

import numpy as np
from neuron import h, init  # Import NEURON
from . import utils


# ------------------------------------------------------------------------------
# Commands required just before running simulation
# ------------------------------------------------------------------------------
[docs] def preRun(): """ Function for/to <short description of `netpyne.sim.run.preRun`> """ from .. import sim # set initial v of cells for cell in sim.net.cells: sim.fih.append(h.FInitializeHandler(0, cell.initV)) # cvode variables sim.cvode.active(int(sim.cfg.cvode_active)) sim.cvode.cache_efficient(int(sim.cfg.cache_efficient)) sim.cvode.atol(sim.cfg.cvode_atol) sim.cvode.use_fast_imem(sim.cfg.use_fast_imem) # set h global params sim.setGlobals() # set h.dt h.dt = sim.cfg.dt if sim.cfg.coreneuron: sim.cfg.random123 = True # set v_init if doesn't exist if 'v_init' not in sim.cfg.hParams: sim.cfg.hParams['v_init'] = -65.0 # parallelcontext vars sim.pc.set_maxstep(10) mindelay = sim.pc.allreduce(sim.pc.set_maxstep(10), 2) # flag 2 returns minimum value if sim.rank == 0 and sim.cfg.verbose: print(('Minimum delay (time-step for queue exchange) is %.2f' % (mindelay))) sim.pc.setup_transfer() # setup transfer of source_var to target_var # handler for printing out time during simulation run if sim.rank == 0 and sim.cfg.printRunTime: def printRunTime(): print('%.1fs' % (h.t / 1000.0)) sim.cvode.event(h.t + int(sim.cfg.printRunTime * 1000.0), sim.printRunTime) sim.printRunTime = printRunTime sim.fih.append(h.FInitializeHandler(1, sim.printRunTime)) # set global index used by all instances of the Random123 instances of Random if sim.cfg.rand123GlobalIndex is not None: rand = h.Random() rand.Random123_globalindex(int(sim.cfg.rand123GlobalIndex)) # reset all netstim randomizers so runs are always equivalent for cell in sim.net.cells: if cell.tags.get('cellModel') == 'NetStim': # cell.hRandom.Random123(sim.hashStr('NetStim'), cell.gid, cell.params['seed']) if sim.cfg.random123: cell.hPointp.noiseFromRandom123(utils.hashStr('NetStim'), cell.gid, cell.params['seed']) else: utils._init_stim_randomizer(cell.hRandom, 'NetStim', cell.gid, cell.params['seed']) cell.hRandom.negexp(1) cell.hPointp.noiseFromRandom(cell.hRandom) pop = sim.net.pops[cell.tags['pop']] if 'originalFormat' in pop.tags and pop.tags['originalFormat'] == 'NeuroML2_SpikeSource': if sim.cfg.verbose: print("== Setting random generator in NeuroML spike generator") cell.initRandom() else: for stim in cell.stims: if 'hRandom' in stim: # stim['hRandom'].Random123(sim.hashStr(stim['source']), cell.gid, stim['seed']) if not sim.cfg.random123: utils._init_stim_randomizer(stim['hRandom'], stim['type'], cell.gid, stim['seed']) stim['hRandom'].negexp(1) # Check if noiseFromRandom is in stim['hObj']; see https://github.com/Neurosim-lab/netpyne/issues/219 if not isinstance(stim['hObj'].noiseFromRandom, dict): if sim.cfg.random123: stim['hObj'].noiseFromRandom123(sim.hashStr(stim['type']), cell.gid, stim['seed']) else: stim['hObj'].noiseFromRandom(stim['hRandom']) # handler for recording LFP if sim.cfg.recordLFP: def recordLFPHandler(): sim.cvode.event(h.t + float(sim.cfg.recordStep), sim.calculateLFP) sim.cvode.event(h.t + float(sim.cfg.recordStep), recordLFPHandler) sim.recordLFPHandler = recordLFPHandler sim.fih.append(h.FInitializeHandler(0, sim.recordLFPHandler)) # initialize imemb # handler for recording LFP if sim.cfg.recordDipole: def recordDipoleHandler(): sim.cvode.event(h.t + float(sim.cfg.recordStep), sim.calculateDipole) sim.cvode.event(h.t + float(sim.cfg.recordStep), sim.recordDipoleHandler) sim.recordDipoleHandler = recordDipoleHandler sim.fih.append(h.FInitializeHandler(0, sim.recordDipoleHandler)) # initialize imemb
# ------------------------------------------------------------------------------ # Run Simulation # ------------------------------------------------------------------------------
[docs] def runSim(skipPreRun=False): """ Function for/to <short description of `netpyne.sim.run.runSim`> Parameters ---------- skipPreRun : bool <Short description of skipPreRun> **Default:** ``False`` **Options:** ``<option>`` <description of option> """ from .. import sim sim.pc.barrier() if hasattr(sim.cfg, 'use_local_dt') and sim.cfg.use_local_dt: try: sim.cvode.use_local_dt(1) if sim.cfg.verbose: print('Using local dt.') except: if sim.cfg.verbose: 'Error Failed to use local dt.' sim.pc.barrier() sim.timing('start', 'runTime') if not skipPreRun: preRun() h.finitialize(float(sim.cfg.hParams['v_init'])) if sim.cfg.dump_coreneuron_model: sim.pc.nrnbbcore_write("coredat") if sim.rank == 0: print('\nDumping model and exiting simulation...') sim.pc.barrier() return if sim.cfg.coreneuron == True: if sim.rank == 0: print('\nRunning simulation using CoreNEURON for %s ms...' % sim.cfg.duration) from neuron import coreneuron coreneuron.enable = True if sim.cfg.gpu == True: coreneuron.gpu = True coreneuron.cell_permute = 2 else: if sim.rank == 0: print('\nRunning simulation using NEURON for %s ms...' % sim.cfg.duration) postRun()
[docs] def postRun(stopTime=None): """ Function for/to <short description of `netpyne.sim.run.postRun`> """ from .. import sim if (stopTime is None) or (stopTime != sim.cfg.duration): sim.pc.psolve(sim.cfg.duration) sim.pc.barrier() # Wait for all hosts to get to this point sim.timing('stop', 'runTime') if sim.rank == 0: print( ' Done; run time = %0.2f s; real-time ratio: %0.2f.' % (sim.timingData['runTime'], sim.cfg.duration / 1000 / sim.timingData['runTime']) )
# ------------------------------------------------------------------------------ # Run Simulation with a function executed at intervals # ------------------------------------------------------------------------------
[docs] def runSimWithIntervalFunc(interval, func, timeRange=None, funcArgs=None): """ Function to run a simulation while executing a function at intervals Parameters ---------- interval : float Time interval (ms) at which to execute the function **Default:** *required* func : function The function to be executed at intervals. The first positional argument (float) is the current progress of simulation in ms. The rest of the arguments have to correspond to those optionally provided in `funcArgs`. **Default:** *required* timeRange : list Time range during which to execute the function [intervalStart, intervalStop] **Default:** `None` uses the entire simulation duration funcArgs: dict A dictionary of keyword arguments to feed into the function. **Default:** `None` """ stopTime, kwargs = prepareSimWithIntervalFunc(timeRange, funcArgs) while round(h.t) < stopTime: runForInterval(interval, func, **kwargs) postRun(stopTime)
[docs] def prepareSimWithIntervalFunc(timeRange=None, funcArgs=None): """ Function for/to <short description of `netpyne.sim.run.prepareSimWithIntervalFunc`> """ from .. import sim sim.pc.barrier() sim.timing('start', 'runTime') preRun() h.finitialize(float(sim.cfg.hParams['v_init'])) startTime = 0 stopTime = sim.cfg.duration if timeRange is not None: startTime = timeRange[0] stopTime = timeRange[1] kwargs = {} if type(funcArgs) == dict: kwargs.update(funcArgs) if sim.cfg.coreneuron == True: if sim.rank == 0: print('\nRunning with interval func using CoreNEURON for %s ms...' % sim.cfg.duration) from neuron import coreneuron coreneuron.enable = True if sim.cfg.gpu == True: coreneuron.gpu = True coreneuron.cell_permute = 2 else: if sim.rank == 0: print('\nRunning with interval func using NEURON for %s ms...' % sim.cfg.duration) if int(startTime) != 0: sim.pc.psolve(startTime) sim.pc.barrier() return stopTime, kwargs
[docs] def runForInterval(interval, func, **kwargs): from .. import sim sim.pc.psolve(min(sim.cfg.duration, h.t + interval)) func(h.t, **kwargs) # function to be called at intervals
# ------------------------------------------------------------------------------ # Calculate LFP (fucntion called at every time step) # ------------------------------------------------------------------------------
[docs] def calculateLFP(): """ Function for/to <short description of `netpyne.sim.run.calculateLFP`> """ from .. import sim # Set pointers to i_membrane in each cell (required form LFP calc ) for cell in sim.net.compartCells: cell.setImembPtr() # compute saveStep = int(np.floor(h.t / sim.cfg.recordStep)) for cell in sim.net.compartCells: # compute ecp only from the biophysical cells gid = cell.gid im = cell.getImemb() # in nA tr = sim.net.recXElectrode.getTransferResistance(gid) # in MOhm ecp = np.dot(tr, im) # in mV (= R * I = MOhm * nA) if sim.cfg.saveLFPPops: if cell.gid in sim.net.popForEachGid: pop = sim.net.popForEachGid[cell.gid] sim.simData['LFPPops'][pop][ saveStep - 1, : ] += ecp # contribution of individual cells (stored optionally) if sim.cfg.saveLFPCells and gid in sim.simData['LFPCells']: sim.simData['LFPCells'][gid][saveStep - 1, :] = ecp # contribution of individual cells (stored optionally) sim.simData['LFP'][saveStep - 1, :] += ecp # sum of all cells
# ------------------------------------------------------------------------------ # Calculate LFP (fucntion called at every time step) # ------------------------------------------------------------------------------
[docs] def calculateDipole(): """ Function for/to <short description of `netpyne.sim.run.calculateLFP`> """ from .. import sim import lfpykit # Set pointers to i_membrane in each cell (required for LFP calc ) for cell in sim.net.compartCells: cell.setImembPtr() # import IPython as ipy; ipy.embed() # compute saveStep = int(np.floor(h.t / sim.cfg.recordStep)) for cell in sim.net.compartCells: # compute ecp only from the biophysical cells gid = cell.gid im = cell.getImemb() # in nA p = cell.M @ im if sim.cfg.saveDipolePops: if cell.gid in sim.net.popForEachGid: pop = sim.net.popForEachGid[cell.gid] sim.simData['dipolePops'][pop][ saveStep - 1 ] += p # contribution of individual cells (stored optionally) if sim.cfg.saveDipoleCells and gid in sim.simData['dipoleCells']: sim.simData['dipoleCells'][gid][saveStep - 1] = p # contribution of individual cells (stored optionally) sim.simData['dipoleSum'][saveStep - 1] += p # sum of all cells
# ------------------------------------------------------------------------------ # Calculate and print load balance # ------------------------------------------------------------------------------
[docs] def loadBalance(printNodeTimes=False): """ Function for/to <short description of `netpyne.sim.run.loadBalance`> Parameters ---------- printNodeTimes : bool <Short description of printNodeTimes> **Default:** ``False`` **Options:** ``<option>`` <description of option> """ from .. import sim computation_time = sim.pc.step_time() max_comp_time = sim.pc.allreduce(computation_time, 2) min_comp_time = sim.pc.allreduce(computation_time, 3) avg_comp_time = sim.pc.allreduce(computation_time, 1) / sim.nhosts load_balance = avg_comp_time / max_comp_time if printNodeTimes: print('node:', sim.rank, ' comp_time:', computation_time) if sim.rank == 0: print('max_comp_time:', max_comp_time) print('min_comp_time:', min_comp_time) print('avg_comp_time:', avg_comp_time) print('load_balance:', load_balance) print('\nspike exchange time (run_time-comp_time): ', sim.timingData['runTime'] - max_comp_time) return [max_comp_time, min_comp_time, avg_comp_time, load_balance]