def createNeurone(name, component_info, rng, parameters): """ Returns daetoolsComponent object based on the supplied daetoolsComponentInfo object. There are some special cases which are handled individually such as: * SpikeSourcePoisson :param name: string :param component_info: AL Component object :param rng: numpy.random.RandomState object :param parameters: python dictionary 'name' : value :rtype: daetoolsComponent object :raises: RuntimeError """ neurone = None """ ACHTUNG, ACHTUNG!! We should handle components' with names that mean something. How can we know that the spike_source_poisson component should be treated differently by a simulator? The same stands for other types of components. """ if component_info.name == 'spike_source_poisson': if 'rate' in parameters: # Create daetools quantity and scale it to 'Hz' rate = pyUnits.quantity(parameters['rate'][0], parameters['rate'][1]).scaleTo(pyUnits.Hz) #print('spike_source_poisson.rate = %s' % rate) else: raise RuntimeError('The SpikeSourcePoisson component: must have [rate] parameter') if 'duration' in parameters: # Create daetools quantity and scale it to 's' duration = pyUnits.quantity(parameters['duration'][0], parameters['duration'][1]).scaleTo(pyUnits.s) #print('spike_source_poisson.duration = %s' % duration) else: raise RuntimeError('The SpikeSourcePoisson component: must have [duration] parameter') if 't0' in parameters: # Create daetools quantity and scale it to 's' t0 = pyUnits.quantity(parameters['t0'][0], parameters['t0'][1]).scaleTo(pyUnits.s) #print('spike_source_poisson.t0 = %s' % t0) else: t0 = 0.0 # Should be rate [Hz] * duration [s] lambda_ = rate.value * duration.value spiketimes = createPoissonSpikeTimes(rate, duration, t0, rng, lambda_, rng) neurone = daetoolsSpikeSource(spiketimes, name, None, '') else: neurone = daetoolsComponent(component_info, fixObjectName(name), None, '') neurone.Nitems = 1 neurone.initialize() spike_event_port = neurone.getOutletEventPort() neurone.on_spike_out_action = daetoolsOnSpikeOutAction(neurone, spike_event_port) neurone.ON_EVENT(spike_event_port, userDefinedActions = [neurone.on_spike_out_action]) return neurone
def createConnections(self, cgi, source_population, target_population, psr_weight_units, connrule_weight_units, connrule_delay_units): """ Iterates over ConnectionGeneratorInterface object and creates connections. It connects source->target neurones and (optionally) sets weights and delays :param cgi: ConnectionGenerator interface object :rtype: None :raises: RuntimeError """ count = 0 for connection in cgi: size = len(connection) if(size < 2): raise RuntimeError('Not enough data in the explicit lists of connections') source_index = int(connection[0]) target_index = int(connection[1]) weight = 0.0 delay = 0.0 parameters = [] # Weight and delay values are in units specified by the user in the UL component # Weight will be scaled to the units in the PSR component, while delay to seconds if cgi.arity == 1: weight = pyUnits.quantity(float(connection[2]), connrule_weight_units) elif cgi.arity >= 2: weight = pyUnits.quantity(float(connection[2]), connrule_weight_units) delay = pyUnits.quantity(float(connection[3]), connrule_delay_units) source_neurone = source_population.getNeurone(source_index) target_neurone = target_population.getNeurone(target_index) synapse = self.getSynapse(target_index) # Scale the delay to seconds delay_in_seconds = delay.scaleTo(pyUnits.s).value #print('delay_in_seconds = %f' % delay_in_seconds) if delay_in_seconds < self.minimal_delay: self.minimal_delay = delay_in_seconds # Add the new item to the list of connected synapse event ports and connection delays. # Here we cannot add an event port directly since it does not exist yet. # Therefore, we add the synapse object and the index of the event port. source_neurone.target_synapses.append( (synapse, synapse.Nitems, delay_in_seconds, target_neurone) ) synapse.Nitems += 1 # Weights cannot be set right now. Thus, we put them into an array. # Also, the units must be scaled to those specified in the PSR component synapse.synapse_weights.append( weight.scaleTo(psr_weight_units) ) count += 1 print('{0}: created {1} connections'.format(self.name, count))
def createNeurone(name, component_info, rng, parameters): """ Returns daetoolsComponent object based on the supplied daetoolsComponentInfo object. There are some special cases which are handled individually such as: * SpikeSourcePoisson :param name: string :param component_info: AL Component object :param rng: numpy.random.RandomState object :param parameters: python dictionary 'name' : value :rtype: daetoolsComponent object :raises: RuntimeError """ neurone = None """ ACHTUNG, ACHTUNG!! We should handle components' with names that mean something. How can we know that the spike_source_poisson component should be treated differently by a simulator? The same stands for other types of components. """ if component_info.name == 'spike_source_poisson': if 'rate' in parameters: # Create daetools quantity and scale it to 'Hz' rate = pyUnits.quantity(parameters['rate'][0], parameters['rate'][1]).scaleTo(pyUnits.Hz) #print('spike_source_poisson.rate = %s' % rate) else: raise RuntimeError( 'The SpikeSourcePoisson component: must have [rate] parameter') if 'duration' in parameters: # Create daetools quantity and scale it to 's' duration = pyUnits.quantity(parameters['duration'][0], parameters['duration'][1]).scaleTo( pyUnits.s) #print('spike_source_poisson.duration = %s' % duration) else: raise RuntimeError( 'The SpikeSourcePoisson component: must have [duration] parameter' ) if 't0' in parameters: # Create daetools quantity and scale it to 's' t0 = pyUnits.quantity(parameters['t0'][0], parameters['t0'][1]).scaleTo(pyUnits.s) #print('spike_source_poisson.t0 = %s' % t0) else: t0 = 0.0 # Should be rate [Hz] * duration [s] lambda_ = rate.value * duration.value spiketimes = createPoissonSpikeTimes(rate, duration, t0, rng, lambda_, rng) neurone = daetoolsSpikeSource(spiketimes, name, None, '') else: neurone = daetoolsComponent(component_info, fixObjectName(name), None, '') neurone.Nitems = 1 neurone.initialize() spike_event_port = neurone.getOutletEventPort() neurone.on_spike_out_action = daetoolsOnSpikeOutAction( neurone, spike_event_port) neurone.ON_EVENT(spike_event_port, userDefinedActions=[neurone.on_spike_out_action]) return neurone
def createConnections(self, cgi, source_population, target_population, psr_weight_units, connrule_weight_units, connrule_delay_units): """ Iterates over ConnectionGeneratorInterface object and creates connections. It connects source->target neurones and (optionally) sets weights and delays :param cgi: ConnectionGenerator interface object :rtype: None :raises: RuntimeError """ count = 0 for connection in cgi: size = len(connection) if (size < 2): raise RuntimeError( 'Not enough data in the explicit lists of connections') source_index = int(connection[0]) target_index = int(connection[1]) weight = 0.0 delay = 0.0 parameters = [] # Weight and delay values are in units specified by the user in the UL component # Weight will be scaled to the units in the PSR component, while delay to seconds if cgi.arity == 1: weight = pyUnits.quantity(float(connection[2]), connrule_weight_units) elif cgi.arity >= 2: weight = pyUnits.quantity(float(connection[2]), connrule_weight_units) delay = pyUnits.quantity(float(connection[3]), connrule_delay_units) source_neurone = source_population.getNeurone(source_index) target_neurone = target_population.getNeurone(target_index) synapse = self.getSynapse(target_index) # Scale the delay to seconds delay_in_seconds = delay.scaleTo(pyUnits.s).value #print('delay_in_seconds = %f' % delay_in_seconds) if delay_in_seconds < self.minimal_delay: self.minimal_delay = delay_in_seconds # Add the new item to the list of connected synapse event ports and connection delays. # Here we cannot add an event port directly since it does not exist yet. # Therefore, we add the synapse object and the index of the event port. source_neurone.target_synapses.append( (synapse, synapse.Nitems, delay_in_seconds, target_neurone)) synapse.Nitems += 1 # Weights cannot be set right now. Thus, we put them into an array. # Also, the units must be scaled to those specified in the PSR component synapse.synapse_weights.append(weight.scaleTo(psr_weight_units)) count += 1 print('{0}: created {1} connections'.format(self.name, count))