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 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 __init__(self, name, ul_projection, group, network):
        """
        :param name: string
        :param ul_projection: UL Projection object
        :param group: daetoolsGroup object
        :param network: daetoolsPointNeuroneNetwork object
        
        :rtype:
        :raises: RuntimeError
        """
        self.name          = fixObjectName(name)
        self.minimal_delay = 1.0e10
        
        if not isinstance(ul_projection.source.prototype, nineml.user_layer.SpikingNodeType):
            raise RuntimeError('Currently, only populations of spiking neurones (not groups) are supported')
        if not isinstance(ul_projection.target.prototype, nineml.user_layer.SpikingNodeType):
            raise RuntimeError('Currently, only populations of spiking neurones (not groups) are supported')
        
        source_population          = group.getPopulation(ul_projection.source.name)
        target_population          = group.getPopulation(ul_projection.target.name)
        psr_parameters             = network.getComponentParameters(ul_projection.synaptic_response.name)
        connection_rule            = network.getALComponent(ul_projection.rule.name)
        connection_rule_parameters = network.getComponentParameters(ul_projection.rule.name)
        connection_type            = network.getALComponent(ul_projection.connection_type.name)
        psr_component_info         = network.getComponentInfo(ul_projection.synaptic_response.name)
        source_name                = fixObjectName(ul_projection.source.name)
        target_name                = fixObjectName(ul_projection.target.name)
        synapse_name               = fixObjectName(ul_projection.synaptic_response.name)
        
        self._synapses = [
                          daetoolsComponent(
                                             psr_component_info, 
                                            's(p{0},p{1})'.format(source_population._population_id, target_population._population_id),
                                            target_population.getNeurone(i), 
                                            ''
                                           ) for i in xrange(0, ul_projection.target.number)
                         ]               
        
        for i, neurone in enumerate(target_population.neurones):
            neurone.incoming_synapses.append( (self._synapses[i], psr_parameters) ) 
        
        if 'weight' in psr_parameters:
            paramWeight      = psr_parameters['weight']
            psr_weight_units = paramWeight[1]
        else:
            raise RuntimeError('Could not find a parameter with the name [weight] in the synapse {0}'.format(model.Name))

        #print('connection_rule_parameters: %s' % connection_rule_parameters)
        if 'weight' in connection_rule_parameters:
            connrule_weight_units  = connection_rule_parameters['weight'][1]
        else:
            raise RuntimeError('Could not find a parameter with the name [weight] in the connection rule {0}'.format(model.Name))

        if 'delay' in connection_rule_parameters:
            connrule_delay_units  = connection_rule_parameters['delay'][1]
        else:
            raise RuntimeError('Could not find a parameter with the name [delay] in the connection rule {0}'.format(model.Name))
        
        # Create an object that supports the Geometry interface 
        geometry = geometryFromProjection(ul_projection)
        #print('Metric({0},{1}) = {2}'.format(0, 15, geometry.metric(0, 15)))
        
        # Create an object that supports the ConnectionGenerator interface and set-up connections
        mask = connection_generator.Mask([(0, ul_projection.source.number - 1)], [(0, ul_projection.target.number - 1)])
        cgi = connectionGeneratorFromProjection(ul_projection, geometry)
        cgi.setMask(mask)
        self.createConnections(cgi, source_population, target_population, psr_weight_units, connrule_weight_units, connrule_delay_units)
        
        # Now we are done with connections. Initialize synapses
        for i, neurone in enumerate(target_population.neurones):
            synapse = self._synapses[i]
            synapse.initialize()
            neurone.connectAnaloguePorts(synapse, neurone)
    def __init__(self, name, ul_projection, group, network):
        """
        :param name: string
        :param ul_projection: UL Projection object
        :param group: daetoolsGroup object
        :param network: daetoolsPointNeuroneNetwork object
        
        :rtype:
        :raises: RuntimeError
        """
        self.name = fixObjectName(name)
        self.minimal_delay = 1.0e10

        if not isinstance(ul_projection.source.prototype,
                          nineml.user_layer.SpikingNodeType):
            raise RuntimeError(
                'Currently, only populations of spiking neurones (not groups) are supported'
            )
        if not isinstance(ul_projection.target.prototype,
                          nineml.user_layer.SpikingNodeType):
            raise RuntimeError(
                'Currently, only populations of spiking neurones (not groups) are supported'
            )

        source_population = group.getPopulation(ul_projection.source.name)
        target_population = group.getPopulation(ul_projection.target.name)
        psr_parameters = network.getComponentParameters(
            ul_projection.synaptic_response.name)
        connection_rule = network.getALComponent(ul_projection.rule.name)
        connection_rule_parameters = network.getComponentParameters(
            ul_projection.rule.name)
        connection_type = network.getALComponent(
            ul_projection.connection_type.name)
        psr_component_info = network.getComponentInfo(
            ul_projection.synaptic_response.name)
        source_name = fixObjectName(ul_projection.source.name)
        target_name = fixObjectName(ul_projection.target.name)
        synapse_name = fixObjectName(ul_projection.synaptic_response.name)

        self._synapses = [
            daetoolsComponent(
                psr_component_info,
                's(p{0},p{1})'.format(source_population._population_id,
                                      target_population._population_id),
                target_population.getNeurone(i), '')
            for i in xrange(0, ul_projection.target.number)
        ]

        for i, neurone in enumerate(target_population.neurones):
            neurone.incoming_synapses.append(
                (self._synapses[i], psr_parameters))

        if 'weight' in psr_parameters:
            paramWeight = psr_parameters['weight']
            psr_weight_units = paramWeight[1]
        else:
            raise RuntimeError(
                'Could not find a parameter with the name [weight] in the synapse {0}'
                .format(model.Name))

        #print('connection_rule_parameters: %s' % connection_rule_parameters)
        if 'weight' in connection_rule_parameters:
            connrule_weight_units = connection_rule_parameters['weight'][1]
        else:
            raise RuntimeError(
                'Could not find a parameter with the name [weight] in the connection rule {0}'
                .format(model.Name))

        if 'delay' in connection_rule_parameters:
            connrule_delay_units = connection_rule_parameters['delay'][1]
        else:
            raise RuntimeError(
                'Could not find a parameter with the name [delay] in the connection rule {0}'
                .format(model.Name))

        # Create an object that supports the Geometry interface
        geometry = geometryFromProjection(ul_projection)
        #print('Metric({0},{1}) = {2}'.format(0, 15, geometry.metric(0, 15)))

        # Create an object that supports the ConnectionGenerator interface and set-up connections
        mask = connection_generator.Mask(
            [(0, ul_projection.source.number - 1)],
            [(0, ul_projection.target.number - 1)])
        cgi = connectionGeneratorFromProjection(ul_projection, geometry)
        cgi.setMask(mask)
        self.createConnections(cgi, source_population, target_population,
                               psr_weight_units, connrule_weight_units,
                               connrule_delay_units)

        # Now we are done with connections. Initialize synapses
        for i, neurone in enumerate(target_population.neurones):
            synapse = self._synapses[i]
            synapse.initialize()
            neurone.connectAnaloguePorts(synapse, neurone)