Source code for netpyne.cell.inputs

"""
Module with functions to create patterned spike inputs in cells

"""

from numbers import Number

try:
    basestring
except NameError:
    basestring = str

from neuron import h
import numpy as np


[docs] def createRhythmicPattern(params, rand): """ Creates the ongoing external inputs (rhythmic) input params: - start: time of first spike. if -1, uniform distribution between startMin and startMax (ms) - startMin: minimum values of uniform distribution for start time (ms) - startMax: maximum values of uniform distribution for start time (ms) - startStd: standard deviation of normal distrinution for start time (ms); mean is set by start param. Only used if > 0.0 - freq: oscillatory frequency of rhythmic pattern (Hz) - freqStd: standard deviation of oscillatory frequency (Hz) - distribution: distribution type for oscillatory frequencies; either 'normal' or 'uniform' - eventsPerCycle: spikes/burst per cycle; should be either 1 or 2 - repeats: number of times to repeat input pattern (equivalent to number of inputs) - stop: maximum time for last spike of pattern (ms) - tstop: maximum time for last spike of pattern (ms) (maintained for backward compatibility) """ #TODO catch KeyError cases? # start is always defined start = params['start'] if 'stop' in params: stop = params['stop'] elif 'tstop' in params: stop = params['tstop'] else: print('stop / tstop time not defined, please provide stop time') return np.array([]) # If start is -1, randomize start time of inputs if start == -1: startMin = params.get('startMin', 25.0) startMax = params.get('startMax', 125.0) start = rand.uniform(startMin, startMax) elif params.get('startStd', -1) > 0.0: # randomize start time based on startStd start = rand.normal(start, params['startStd']) # start time uses different prng freq = params.get('freq', False) # if freq not supplied, "exit" control flow w/ print statement freqStd = params.get('freqStd', 0) eventsPerCycle = params.get('eventsPerCycle', 2) distribution = params.get('distribution', 'normal') if eventsPerCycle > 2 or eventsPerCycle <= 0: print("eventsPerCycle should be either 1 or 2, trying 2") eventsPerCycle = 2 # If frequency is False, create empty vector if input times if not freq: #TODO clarification, why not raise?, should error? print("No frequency specified. Not making any alpha feeds.") t_input = [] elif distribution == 'normal': # array of mean stimulus times, starts at start isi_array = np.arange(start, stop, 1000.0 / freq) # array of single stimulus times -- no doublets if freqStd: # t_array = self.prng.normal(np.repeat(isi_array, self.p_ext['repeats']), stdev) # t_array = np.array([rand.normal(x, freqStd) for x in np.repeat(isi_array, params['repeats'])]) # not efficient! isi_array_repeat = np.repeat(isi_array, params['repeats']) stdvec = h.Vector(int(len(isi_array_repeat))) rand.normal(0, freqStd * freqStd) stdvec.setrand(rand) t_array = np.array([mean + std for (mean, std) in zip(list(stdvec), isi_array_repeat)]) else: t_array = isi_array if eventsPerCycle == 2: # spikes/burst in GUI # Two arrays store doublet times t_array_low = t_array - 5 t_array_high = t_array + 5 # Array with ALL stimulus times for input # np.append concatenates two np arrays t_input = np.append(t_array_low, t_array_high) elif eventsPerCycle == 1: t_input = t_array # brute force remove zero times. Might result in fewer vals than desired t_input = t_input[t_input > 0] t_input.sort() # Uniform Distribution elif distribution == 'uniform': n_inputs = params['repeats'] * freq * (stop - start) / 1000.0 rand.uniform(start, stop) vec = h.Vector(int(n_inputs)) t_array = np.array(vec.setrand(rand)) if eventsPerCycle == 2: # Two arrays store doublet times t_input_low = t_array - 5 t_input_high = t_array + 5 # Array with ALL stimulus times for input # np.append concatenates two np arrays t_input = np.append(t_input_low, t_input_high) elif eventsPerCycle == 1: t_input = t_array # brute force remove non-zero times. Might result in fewer vals than desired t_input = t_input[t_input > 0] t_input.sort() else: print("Indicated distribution not recognized. Not making any alpha feeds.") t_input = [] return np.array(t_input)
[docs] def createEvokedPattern(params, rand, inc=0): """ creates the ongoing external inputs (rhythmic) input params: - start: time of first spike. - inc: increase in time of first spike; from cfg.inc_evinput (ms) - startStd: standard deviation of start (ms) - numspikes: total number of spikes to generate """ # assign the params mu = params['start'] + inc sigma = params['startStd'] # self.p_ext[self.celltype][3] # index 3 is sigma_t_ (stdev) numspikes = int(params['numspikes']) # if a non-zero sigma is specified if sigma: # val_evoked = rand.uniform(mu, sigma, numspikes) vec_evoked = h.Vector(int(numspikes)) rand.normal(mu, sigma) vec_evoked.setrand(rand) val_evoked = np.array(vec_evoked) else: # if sigma is specified at 0 val_evoked = np.array([mu] * numspikes) val_evoked = val_evoked[val_evoked > 0] # vals must be sorted val_evoked.sort() return val_evoked
[docs] def createPoissonPattern(params, rand): """ creates external Poisson inputs input params: - start: time of first spike (ms) - stop: stop time; if -1 the full duration (ms) - frequency: standard deviation of start (ms) """ # new external pois designation t0 = params['start'] # self.p_ext['t_interval'][0] T = params['stop'] # self.p_ext['t_interval'][1] lamtha = params['frequency'] # self.p_ext[self.celltype][3] # index 3 is frequency (lamtha) # values MUST be sorted for VecStim()! # start the initial value val_pois = np.array([]) if lamtha > 0.0: t_gen = t0 + (-1000.0 * np.log(1.0 - rand.uniform(0, 1)) / lamtha) if t_gen < T: np.append(val_pois, t_gen) # vals are guaranteed to be monotonically increasing, no need to sort while t_gen < T: # so as to not clobber confusingly base off of t_gen ... t_gen += -1000.0 * np.log(1.0 - rand.uniform(0, 1)) / lamtha if t_gen < T: val_pois = np.append(val_pois, t_gen) return val_pois
[docs] def createGaussPattern(params, rand): """ Creates Gaussian inputs input params: - mu: Gaussian mean - sigma: Gaussian variance """ # set params mu = params['mu'] sigma = params['sigma'] numspikes = 50 # generate values from gauss distribution vec_gauss = h.Vector(int(numspikes)) rand.normal(mu, sigma) vec_gauss.setrand(rand) val_gauss = np.array(vec_gauss) # remove < 0 values and sort val_gauss = val_gauss[val_gauss > 0] val_gauss = np.sort(val_gauss) return val_gauss