Пример #1
0
    def custom_operation(self, code, when=None, name=None):
        '''
        Returns a `CodeRunner` that runs abstract code in the group's namespace.

        Parameters
        ----------
        code : str
            The abstract code to run.
        when : `Scheduler`, optional
            When to run, by default in the 'stateupdate' slot with the same
            clock as the group.
        name : str, optional
            A unique name, if non is given the name of the group appended with
            'custom_operation', 'custom_operation_1', etc. will be used. If a
            name is given explicitly, it will be used as given (i.e. the group
            name will not be prepended automatically).
        '''
        when = Scheduler(when)
        if not when.defined_clock:
            when.clock = self.clock

        if name is None:
            name = self.name + '_custom_operation*'

        runner = CodeRunner(self,
                            'stateupdate',
                            code=code,
                            name=name,
                            when=when)
        return runner
Пример #2
0
    def __init__(self, source, when=None, name='ratemonitor*',
                 codeobj_class=None):
        self.source = weakref.proxy(source)

        # run by default on source clock at the end
        scheduler = Scheduler(when)
        if not scheduler.defined_clock:
            scheduler.clock = source.clock
        if not scheduler.defined_when:
            scheduler.when = 'end'

        self.codeobj_class = codeobj_class
        BrianObject.__init__(self, when=scheduler, name=name)

        # create data structures
        self.reinit()

        self.variables = {'t': AttributeVariable(second, self.clock, 't'),
                           'dt': AttributeVariable(second, self.clock,
                                                   'dt', constant=True),
                           '_spikes': AttributeVariable(Unit(1),
                                                        self.source, 'spikes'),
                           # The template needs to have access to the
                           # DynamicArray here, having access to the underlying
                           # array is not enough since we want to do the resize
                           # in the template
                           '_rate': Variable(Unit(1), self._rate),
                           '_t': Variable(Unit(1), self._t),
                           '_num_source_neurons': Variable(Unit(1),
                                                           len(self.source))}
Пример #3
0
    def __init__(self, source, variables, record=None, when=None,
                 name='statemonitor*', codeobj_class=None):
        self.source = weakref.proxy(source)
        self.codeobj_class = codeobj_class

        # run by default on source clock at the end
        scheduler = Scheduler(when)
        if not scheduler.defined_clock:
            scheduler.clock = source.clock
        if not scheduler.defined_when:
            scheduler.when = 'end'

        BrianObject.__init__(self, when=scheduler, name=name)

        # variables should always be a list of strings
        if variables is True:
            variables = source.equations.names
        elif isinstance(variables, str):
            variables = [variables]
        #: The variables to record
        self.record_variables = variables

        # record should always be an array of ints
        self.record_all = False
        if record is True:
            self.record_all = True
            record = source.item_mapping[:]
        elif record is None or record is False:
            record = np.array([], dtype=np.int32)
        elif isinstance(record, int):
            record = np.array([source.item_mapping[record]], dtype=np.int32)
        else:
            record = np.array(source.item_mapping[record], dtype=np.int32)
            
        #: The array of recorded indices
        self.indices = record
        # create data structures
        self.reinit()
        
        # Setup variables
        self.variables = {}
        for varname in variables:
            var = source.variables[varname]
            if not (np.issubdtype(var.dtype, np.float64) and
                        np.issubdtype(np.float64, var.dtype)):
                raise NotImplementedError(('Cannot record %s with data type '
                                           '%s, currently only values stored as '
                                           'doubles can be recorded.') %
                                          (varname, var.dtype))
            self.variables[varname] = var
            self.variables['_recorded_'+varname] = Variable(Unit(1),
                                                            self._values[varname])

        self.variables['_t'] = Variable(Unit(1), self._t)
        self.variables['_clock_t'] = AttributeVariable(second, self.clock, 't_')
        self.variables['_indices'] = ArrayVariable('_indices', Unit(1),
                                                   self.indices,
                                                   constant=True)

        self._group_attribute_access_active = True
Пример #4
0
    def runner(self, code, when=None, name=None):
        '''
        Returns a `CodeRunner` that runs abstract code in the groups namespace

        Parameters
        ----------
        code : str
            The abstract code to run.
        when : `Scheduler`, optional
            When to run, by default in the 'start' slot with the same clock as
            the group.
        name : str, optional
            A unique name, if non is given the name of the group appended with
            'runner', 'runner_1', etc. will be used. If a name is given
            explicitly, it will be used as given (i.e. the group name will not
            be prepended automatically).
        '''
        when = Scheduler(when)
        if not when.defined_clock:
            when.clock = self.clock

        if name is None:
            name = self.name + '_runner*'

        runner = CodeRunner(self, 'stateupdate', code=code, name=name,
                            when=when)
        return runner
Пример #5
0
    def __init__(self,
                 source,
                 when=None,
                 name='ratemonitor*',
                 codeobj_class=None):
        self.source = weakref.proxy(source)

        # run by default on source clock at the end
        scheduler = Scheduler(when)
        if not scheduler.defined_clock:
            scheduler.clock = source.clock
        if not scheduler.defined_when:
            scheduler.when = 'end'

        self.codeobj_class = codeobj_class
        BrianObject.__init__(self, when=scheduler, name=name)

        # create data structures
        self.reinit()

        self.variables = {
            't': AttributeVariable(second, self.clock, 't'),
            'dt': AttributeVariable(second, self.clock, 'dt', constant=True),
            '_spikes': AttributeVariable(Unit(1), self.source, 'spikes'),
            # The template needs to have access to the
            # DynamicArray here, having access to the underlying
            # array is not enough since we want to do the resize
            # in the template
            '_rate': Variable(Unit(1), self._rate),
            '_t': Variable(Unit(1), self._t),
            '_num_source_neurons': Variable(Unit(1), len(self.source))
        }
Пример #6
0
    def __init__(self, source, variables, record=None, when=None,
                 name='statemonitor*', codeobj_class=None):
        self.source = weakref.proxy(source)
        self.codeobj_class = codeobj_class

        # run by default on source clock at the end
        scheduler = Scheduler(when)
        if not scheduler.defined_clock:
            scheduler.clock = source.clock
        if not scheduler.defined_when:
            scheduler.when = 'end'

        BrianObject.__init__(self, when=scheduler, name=name)

        # variables should always be a list of strings
        if variables is True:
            variables = source.equations.names
        elif isinstance(variables, str):
            variables = [variables]
        #: The variables to record
        self.record_variables = variables

        # record should always be an array of ints
        self.record_all = False
        if record is True:
            self.record_all = True
            record = np.arange(len(source), dtype=np.int32)
        elif record is None or record is False:
            record = np.array([], dtype=np.int32)
        elif isinstance(record, int):
            record = np.array([record], dtype=np.int32)
        else:
            record = np.asarray(record, dtype=np.int32)
            
        #: The array of recorded indices
        self.indices = record
        
        # Setup variables
        self.variables = Variables(self)
        for varname in variables:
            var = source.variables[varname]
            self.variables.add_reference(varname, var,
                                         index=source.variables.indices[varname])
            self.variables.add_dynamic_array('_recorded_' + varname,
                                             size=(0, len(self.indices)),
                                             unit=var.unit,
                                             dtype=var.dtype,
                                             constant=False,
                                             constant_size=False,
                                             is_bool=var.is_bool)

        self.variables.add_dynamic_array('_t', size=0, unit=Unit(1),
                                         constant=False, constant_size=False)
        self.variables.add_attribute_variable('_clock_t', second, self.clock, 't_')
        self.variables.add_array('_indices', size=len(self.indices),
                                 unit=Unit(1), dtype=self.indices.dtype,
                                 constant=True, read_only=True)
        self.variables['_indices'].set_value(self.indices)

        self._group_attribute_access_active = True
Пример #7
0
    def __init__(self,
                 source,
                 record=True,
                 when=None,
                 name='spikemonitor*',
                 codeobj_class=None):
        self.record = bool(record)
        #: The source we are recording from
        self.source = source

        # run by default on source clock at the end
        scheduler = Scheduler(when)
        if not scheduler.defined_clock:
            scheduler.clock = source.clock
        if not scheduler.defined_when:
            scheduler.when = 'end'

        self.codeobj_class = codeobj_class
        CodeRunner.__init__(self,
                            group=self,
                            template='spikemonitor',
                            name=name,
                            when=scheduler)

        # Handle subgroups correctly
        start = getattr(source, 'start', 0)
        stop = getattr(source, 'stop', len(source))

        self.variables = Variables(self)
        self.variables.add_clock_variables(scheduler.clock, prefix='_clock_')
        self.variables.add_reference('_spikespace',
                                     source.variables['_spikespace'])
        self.variables.add_dynamic_array('i',
                                         size=0,
                                         unit=Unit(1),
                                         dtype=np.int32,
                                         constant_size=False)
        self.variables.add_dynamic_array('t',
                                         size=0,
                                         unit=second,
                                         constant_size=False)
        self.variables.add_array('_count',
                                 size=len(source),
                                 unit=Unit(1),
                                 dtype=np.int32)
        self.variables.add_constant('_source_start', Unit(1), start)
        self.variables.add_constant('_source_stop', Unit(1), stop)
        self.variables.add_attribute_variable('N',
                                              unit=Unit(1),
                                              obj=self,
                                              attribute='_N',
                                              dtype=np.int32)
        self._N = 0

        self._enable_group_attributes()
Пример #8
0
    def __init__(self, N, rates, when=None, name=None):
        # TODO: sort out the default values in Scheduler
        scheduler = Scheduler(when)
        scheduler.when = 'thresholds'
        BrianObject.__init__(self, when=scheduler, name=name)

        #: The array of spikes from the most recent time step
        self.spikes = array([], dtype=int)
        
        self.rates = rates
        self.N = N = int(N)
        
        self.pthresh = array(rates*self.clock.dt)
Пример #9
0
    def __init__(self, source, record=True, when=None, name=None):
        self.source = weakref.proxy(source)
        self.record = bool(record)

        # run by default on source clock at the end
        scheduler = Scheduler(when)
        if not scheduler.defined_clock:
            scheduler.clock = source.clock
        if not scheduler.defined_when:
            scheduler.when = 'end'
        BrianObject.__init__(self, when=scheduler, name=name)
        
        # create data structures
        self.reinit()
Пример #10
0
    def runner(self, code, when=None, name=None):
        '''
        Returns a `CodeRunner` that runs abstract code in the groups namespace
        
        Parameters
        ----------
        code : str
            The abstract code to run.
        when : `Scheduler`, optional
            When to run, by default in the 'start' slot with the same clock as
            the group.
        name : str, optional
            A unique name, if non is given the name of the group appended with
            'runner', 'runner_1', etc. will be used. If a name is given
            explicitly, it will be used as given (i.e. the group name will not
            be prepended automatically).
        '''
        if when is None:  # TODO: make this better with default values
            when = Scheduler(clock=self.clock)
        else:
            raise NotImplementedError

        if name is None:
            name = self.name + '_runner*'

        runner = GroupCodeRunner(self,
                                 self.language.template_state_update,
                                 code=code,
                                 name=name,
                                 when=when)
        return runner
Пример #11
0
    def __init__(self, when=None, name='brianobject*'):
        scheduler = Scheduler(when)
        when = scheduler.when
        order = scheduler.order
        clock = scheduler.clock

        Nameable.__init__(self, name)

        # : The ID string determining when the object should be updated in `Network.run`.
        self.when = when

        #: The order in which objects with the same clock and ``when`` should be updated
        self.order = order

        #        #: The `Clock` determining when the object should be updated.
        #        self.clock = clock
        self._clock = clock

        self._contained_objects = []
        self._code_objects = []

        self._active = True

        logger.debug("Created BrianObject with name {self.name}, "
                     "clock name {self.clock.name}, "
                     "when={self.when}, order={self.order}".format(self=self))
Пример #12
0
 def __repr__(self):
     description = ('{classname}(when={scheduler}, name={name})')
     return description.format(classname=self.__class__.__name__,
                               scheduler=repr(
                                   Scheduler(when=self.when,
                                             clock=self.clock,
                                             order=self.order)),
                               name=repr(self.name))
Пример #13
0
    def __init__(self,
                 N,
                 indices,
                 times,
                 when=None,
                 name='spikegeneratorgroup*',
                 codeobj_class=None):
        if when is None:
            when = Scheduler(when='thresholds')
        Group.__init__(self, when=when, name=name)

        self.codeobj_class = codeobj_class

        if N < 1 or int(N) != N:
            raise ValueError('N has to be an integer >=1.')

        if len(indices) != len(times):
            raise ValueError(
                ('Length of the indices and times array must '
                 'match, but %d != %d') % (len(indices), len(times)))

        self.start = 0
        self.stop = N

        # sort times and indices first by time, then by indices
        rec = np.rec.fromarrays([times, indices], names=['t', 'i'])
        rec.sort()
        times = np.ascontiguousarray(rec.t)
        indices = np.ascontiguousarray(rec.i)

        self.variables = Variables(self)

        # standard variables
        self.variables.add_clock_variables(self.clock)
        self.variables.add_constant('N', unit=Unit(1), value=N)
        self.variables.add_arange('i', N)
        self.variables.add_arange('spike_number', len(indices))
        self.variables.add_array('neuron_index',
                                 values=indices,
                                 size=len(indices),
                                 unit=Unit(1),
                                 dtype=np.int32,
                                 index='spike_number',
                                 read_only=True)
        self.variables.add_array('spike_time',
                                 values=times,
                                 size=len(times),
                                 unit=second,
                                 index='spike_number',
                                 read_only=True)
        self.variables.add_array('_spikespace',
                                 size=N + 1,
                                 unit=Unit(1),
                                 dtype=np.int32)
        # Activate name attribute access
        self._enable_group_attributes()

        CodeRunner.__init__(self, self, 'spikegenerator', when=when, name=None)
Пример #14
0
    def __init__(self, source, start, stop, name=None):
        # First check if the source is itself a Subgroup
        # If so, then make this a Subgroup of the original Group
        if isinstance(source, Subgroup):
            source = source.source
            start = start + source.start
            stop = stop + source.start
            self.source = source
        else:
            self.source = weakproxy_with_fallback(source)

        if name is None:
            name = source.name + '_subgroup*'
        # We want to update the spikes attribute after it has been updated
        # by the parent, we do this in slot 'thresholds' with an order
        # one higher than the parent order to ensure it takes place after the
        # parent threshold operation
        schedule = Scheduler(clock=source.clock,
                             when='thresholds',
                             order=source.order + 1)
        Group.__init__(self, when=schedule, name=name)
        self._N = stop - start
        self.start = start
        self.stop = stop

        # All the variables have to go via the _sub_idx to refer to the
        # appropriate values in the source group
        self.variables = Variables(self, default_index='_sub_idx')

        # overwrite the meaning of N and i
        self.variables.add_constant('_offset', unit=Unit(1), value=self.start)
        self.variables.add_reference('_source_i', source, 'i')
        self.variables.add_subexpression('i',
                                         unit=Unit(1),
                                         dtype=source.variables['i'].dtype,
                                         expr='_source_i - _offset')
        self.variables.add_constant('N', unit=Unit(1), value=self._N)
        # add references for all variables in the original group
        self.variables.add_references(source, source.variables.keys())

        # Only the variable _sub_idx itself is stored in the subgroup
        # and needs the normal index for this group
        self.variables.add_arange('_sub_idx',
                                  size=self._N,
                                  start=self.start,
                                  index='_idx')

        for key, value in self.source.variables.indices.iteritems():
            if value not in ('_idx', '0'):
                raise ValueError(
                    ('Do not know how to deal with variable %s '
                     'using  index %s in a subgroup') % (key, value))

        self.namespace = self.source.namespace
        self.codeobj_class = self.source.codeobj_class

        self._enable_group_attributes()
Пример #15
0
    def __init__(self, N, rates, when=None, name='poissongroup*'):
        # TODO: sort out the default values in Scheduler
        scheduler = Scheduler(when)
        scheduler.when = 'thresholds'
        BrianObject.__init__(self, when=scheduler, name=name)

        #: The array of spikes from the most recent time step
        self.spikes = np.array([], dtype=int)
        
        self._rates = np.asarray(rates)
        self.N = N = int(N)
        
        self.pthresh = self._calc_threshold()

        self.variables = {'rates': ArrayVariable('rates', Hz, self._rates,
                                                 group_name=self.name,
                                                 constant=True)}
        Group.__init__(self)
Пример #16
0
    def __init__(self, source, record=True, when=None, name='spikemonitor*',
                 codeobj_class=None):
        self.record = bool(record)
        #: The source we are recording from
        self.source =source

        # run by default on source clock at the end
        scheduler = Scheduler(when)
        if not scheduler.defined_clock:
            scheduler.clock = source.clock
        if not scheduler.defined_when:
            scheduler.when = 'end'

        self.codeobj_class = codeobj_class
        CodeRunner.__init__(self, group=self, template='spikemonitor',
                            name=name, when=scheduler)

        self.add_dependency(source)

        # Handle subgroups correctly
        start = getattr(source, 'start', 0)
        stop = getattr(source, 'stop', len(source))

        self.variables = Variables(self)
        self.variables.add_clock_variables(scheduler.clock, prefix='_clock_')
        self.variables.add_reference('_spikespace', source)
        self.variables.add_dynamic_array('i', size=0, unit=Unit(1),
                                         dtype=np.int32, constant_size=False)
        self.variables.add_dynamic_array('t', size=0, unit=second,
                                         constant_size=False)
        self.variables.add_array('_count', size=len(source), unit=Unit(1),
                                 dtype=np.int32)
        self.variables.add_constant('_source_start', Unit(1), start)
        self.variables.add_constant('_source_stop', Unit(1), stop)
        self.variables.add_attribute_variable('N', unit=Unit(1), obj=self,
                                              attribute='_N', dtype=np.int32)

        self._enable_group_attributes()
Пример #17
0
    def __init__(self, N, rates, when=None, name='poissongroup*'):
        # TODO: sort out the default values in Scheduler
        scheduler = Scheduler(when)
        scheduler.when = 'thresholds'
        BrianObject.__init__(self, when=scheduler, name=name)

        #: The array of spikes from the most recent time step
        self.spikes = np.array([], dtype=int)

        self._rates = np.asarray(rates)
        self.N = N = int(N)

        self.pthresh = self._calc_threshold()

        self.variables = {
            'rates':
            ArrayVariable('rates',
                          Hz,
                          self._rates,
                          group_name=self.name,
                          constant=True)
        }
        Group.__init__(self)
Пример #18
0
    def __init__(self, source, when=None, name='ratemonitor*',
                 codeobj_class=None):

        # run by default on source clock at the end
        scheduler = Scheduler(when)
        if not scheduler.defined_clock:
            scheduler.clock = source.clock
        if not scheduler.defined_when:
            scheduler.when = 'end'

        self.codeobj_class = codeobj_class
        BrianObject.__init__(self, when=scheduler, name=name)

        self.variables = Variables(self)
        self.variables.add_clock_variables(self.clock)
        self.variables.add_dynamic_array('_rate', size=0, unit=hertz,
                                         constant_size=False)
        self.variables.add_dynamic_array('_t', size=0, unit=second,
                                         constant_size=False)
        self.variables.add_constant('_num_source_neurons', unit=Unit(1),
                                    value=len(source))

        GroupCodeRunner.__init__(self, source, 'ratemonitor', when=scheduler)
Пример #19
0
    def __init__(self, source, record=True, when=None, name='spikemonitor*',
                 codeobj_class=None):
        self.source = weakref.proxy(source)
        self.record = bool(record)

        # run by default on source clock at the end
        scheduler = Scheduler(when)
        if not scheduler.defined_clock:
            scheduler.clock = source.clock
        if not scheduler.defined_when:
            scheduler.when = 'end'

        self.codeobj_class = codeobj_class
        BrianObject.__init__(self, when=scheduler, name=name)
        
        # create data structures
        self.reinit()

        # Handle subgroups correctly
        start = getattr(self.source, 'start', 0)
        end = getattr(self.source, 'end', len(self.source))

        self.variables = {'t': AttributeVariable(second, self.clock, 't'),
                           '_spikes': AttributeVariable(Unit(1), self.source,
                                                        'spikes'),
                           # The template needs to have access to the
                           # DynamicArray here, having access to the underlying
                           # array is not enough since we want to do the resize
                           # in the template
                           '_i': Variable(Unit(1), self._i),
                           '_t': Variable(Unit(1), self._t),
                           '_count': ArrayVariable('_count', Unit(1),
                                                   self.count),
                           '_source_start': Variable(Unit(1), start,
                                                     constant=True),
                           '_source_end': Variable(Unit(1), end,
                                                   constant=True)}
Пример #20
0
    def __init__(self, source, variables, record=None, when=None, name=None):
        self.source = weakref.proxy(source)

        # run by default on source clock at the end
        scheduler = Scheduler(when)
        if not scheduler.defined_clock:
            scheduler.clock = source.clock
        if not scheduler.defined_when:
            scheduler.when = 'end'
        BrianObject.__init__(self, when=scheduler, name=name)
        
        # variables should always be a list of strings
        if variables is True:
            variables = source.units.keys()
        elif isinstance(variables, str):
            variables = [variables]
        self.variables = variables
        
        # record should always be an array of ints
        if record is None or record is False:
            record = array([], dtype=int)
        elif record is True:
            record = arange(len(source))
        else:
            record = array(record, dtype=int)
            
        #: The array of recorded indices
        self.indices = record
        
        # create data structures
        self.reinit()
        
        # initialise Group access
        self.units = dict((var, source.units[var]) for var in variables)
        self.arrays = {}
        Group.__init__(self)
Пример #21
0
    def __init__(self, source, name='ratemonitor*', codeobj_class=None):

        #: The group we are recording from
        self.source = source

        scheduler = Scheduler(clock=source.clock, when='end')

        self.codeobj_class = codeobj_class
        CodeRunner.__init__(self,
                            group=self,
                            template='ratemonitor',
                            when=scheduler,
                            name=name)

        self.add_dependency(source)

        self.variables = Variables(self)
        # Handle subgroups correctly
        start = getattr(source, 'start', 0)
        stop = getattr(source, 'stop', len(source))
        self.variables.add_constant('_source_start', Unit(1), start)
        self.variables.add_constant('_source_stop', Unit(1), stop)
        self.variables.add_reference('_spikespace', source)
        self.variables.add_reference('_clock_t', source, 't')
        self.variables.add_reference('_clock_dt', source, 'dt')
        self.variables.add_dynamic_array('rate',
                                         size=0,
                                         unit=hertz,
                                         constant_size=False)
        self.variables.add_dynamic_array('t',
                                         size=0,
                                         unit=second,
                                         constant_size=False)
        self.variables.add_reference('_num_source_neurons', source, 'N')
        self.variables.add_attribute_variable('N',
                                              unit=Unit(1),
                                              obj=self,
                                              attribute='_N',
                                              dtype=np.int32)

        self._enable_group_attributes()
Пример #22
0
    def __init__(self, source, start, end, name=None):
        self.source = weakref.proxy(source)
        if name is None:
            name = source.name + '_subgroup*'
        # We want to update the spikes attribute after it has been updated
        # by the parent, we do this in slot 'thresholds' with an order
        # one higher than the parent order to ensure it takes place after the
        # parent threshold operation
        schedule = Scheduler(clock=source.clock,
                             when='thresholds',
                             order=source.order + 1)
        BrianObject.__init__(self, when=schedule, name=name)
        self.N = end - start
        self.start = start
        self.end = end
        self.offset = start

        self.variables = self.source.variables
        self.variable_indices = self.source.variable_indices
        self.namespace = self.source.namespace
        self.codeobj_class = self.source.codeobj_class

        Group.__init__(self)
Пример #23
0
    def __init__(self, source, name='ratemonitor*', codeobj_class=None):

        #: The group we are recording from
        self.source = source

        scheduler = Scheduler(clock=source.clock, when='end')

        self.codeobj_class = codeobj_class
        CodeRunner.__init__(self,
                            group=self,
                            template='ratemonitor',
                            when=scheduler,
                            name=name)

        self.variables = Variables(self)
        self.variables.add_reference('_spikespace',
                                     source.variables['_spikespace'])
        self.variables.add_reference('_clock_t', source.variables['t'])
        self.variables.add_reference('_clock_dt', source.variables['dt'])
        self.variables.add_dynamic_array('rate',
                                         size=0,
                                         unit=hertz,
                                         constant_size=False)
        self.variables.add_dynamic_array('t',
                                         size=0,
                                         unit=second,
                                         constant_size=False)
        self.variables.add_reference('_num_source_neurons',
                                     source.variables['N'])
        self.variables.add_attribute_variable('N',
                                              unit=Unit(1),
                                              obj=self,
                                              attribute='_N',
                                              dtype=np.int32)
        self._N = 0

        self._enable_group_attributes()
Пример #24
0
    def __init__(self,
                 source,
                 variables,
                 record=None,
                 when=None,
                 name='statemonitor*',
                 codeobj_class=None):
        self.source = weakref.proxy(source)
        self.codeobj_class = codeobj_class

        # run by default on source clock at the end
        scheduler = Scheduler(when)
        if not scheduler.defined_clock:
            scheduler.clock = source.clock
        if not scheduler.defined_when:
            scheduler.when = 'end'

        # variables should always be a list of strings
        if variables is True:
            variables = source.equations.names
        elif isinstance(variables, str):
            variables = [variables]
        #: The variables to record
        self.record_variables = variables

        # record should always be an array of ints
        self.record_all = False
        if record is True:
            self.record_all = True
            record = np.arange(len(source), dtype=np.int32)
        elif record is None or record is False:
            record = np.array([], dtype=np.int32)
        elif isinstance(record, int):
            record = np.array([record], dtype=np.int32)
        else:
            record = np.asarray(record, dtype=np.int32)

        #: The array of recorded indices
        self.indices = record
        self.n_indices = len(record)

        # Some dummy code so that code generation takes care of the indexing
        # and subexpressions
        code = ['_to_record_%s = %s' % (v, v) for v in self.record_variables]
        code = '\n'.join(code)

        CodeRunner.__init__(self,
                            group=self,
                            template='statemonitor',
                            code=code,
                            name=name,
                            when=scheduler,
                            check_units=False)

        # Setup variables
        self.variables = Variables(self)

        self.variables.add_dynamic_array('t',
                                         size=0,
                                         unit=second,
                                         constant=False,
                                         constant_size=False)
        if scheduler.clock is source.clock:
            self.variables.add_reference('_clock_t', source.variables['t'])
        else:
            self.variables.add_attribute_variable('_clock_t',
                                                  unit=second,
                                                  obj=scheduler.clock,
                                                  attribute='t_')
        self.variables.add_attribute_variable('N',
                                              unit=Unit(1),
                                              dtype=np.int32,
                                              obj=self,
                                              attribute='_N')
        self.variables.add_array('_indices',
                                 size=len(self.indices),
                                 unit=Unit(1),
                                 dtype=self.indices.dtype,
                                 constant=True,
                                 read_only=True)
        self.variables['_indices'].set_value(self.indices)

        for varname in variables:
            var = source.variables[varname]
            if var.scalar and len(self.indices) > 1:
                logger.warn(('Variable %s is a scalar variable but it will be '
                             'recorded once for every target.' % varname),
                            once=True)
            index = source.variables.indices[varname]
            self.variables.add_reference(varname, var, index=index)
            if not index in ('_idx', '0') and index not in variables:
                self.variables.add_reference(index, source.variables[index])
            # For subexpressions, we also need all referred variables (if they
            # are not already present, e.g. the t as _clock_t
            if isinstance(var, Subexpression):
                for subexpr_varname in var.identifiers:
                    if subexpr_varname in source.variables:
                        source_var = source.variables[subexpr_varname]
                        index = source.variables.indices[subexpr_varname]
                        if index != '_idx' and index not in variables:
                            self.variables.add_reference(
                                index, source.variables[index])
                        if not source_var in self.variables.values():
                            source_index = source.variables.indices[
                                subexpr_varname]
                            # `translate_subexpression` will later replace
                            # the name used in the original subexpression with
                            # _source_varname
                            self.variables.add_reference('_source_' +
                                                         subexpr_varname,
                                                         source_var,
                                                         index=source_index)
            self.variables.add_dynamic_array('_recorded_' + varname,
                                             size=(0, len(self.indices)),
                                             unit=var.unit,
                                             dtype=var.dtype,
                                             constant=False,
                                             constant_size=False)

        for varname in self.record_variables:
            var = self.source.variables[varname]
            self.variables.add_auxiliary_variable('_to_record_' + varname,
                                                  unit=var.unit,
                                                  dtype=var.dtype,
                                                  scalar=var.scalar)

        self.recorded_variables = dict([
            (varname, self.variables['_recorded_' + varname])
            for varname in self.record_variables
        ])
        recorded_names = [
            '_recorded_' + varname for varname in self.record_variables
        ]

        self.needed_variables = recorded_names
        self.template_kwds = template_kwds = {
            '_recorded_variables': self.recorded_variables
        }
        self._N = 0
        self._enable_group_attributes()
Пример #25
0
    def __init__(self, source, variables, record=None, when=None,
                 name='statemonitor*', codeobj_class=None):
        self.source = weakref.proxy(source)
        self.codeobj_class = codeobj_class

        # run by default on source clock at the end
        scheduler = Scheduler(when)
        if not scheduler.defined_clock:
            scheduler.clock = source.clock
        if not scheduler.defined_when:
            scheduler.when = 'end'

        # variables should always be a list of strings
        if variables is True:
            variables = source.equations.names
        elif isinstance(variables, str):
            variables = [variables]
        #: The variables to record
        self.record_variables = variables

        # record should always be an array of ints
        self.record_all = False
        if record is True:
            self.record_all = True
            record = np.arange(len(source), dtype=np.int32)
        elif record is None or record is False:
            record = np.array([], dtype=np.int32)
        elif isinstance(record, int):
            record = np.array([record], dtype=np.int32)
        else:
            record = np.asarray(record, dtype=np.int32)
            
        #: The array of recorded indices
        self.indices = record
        self.n_indices = len(record)

        # Some dummy code so that code generation takes care of the indexing
        # and subexpressions
        code = ['_to_record_%s = %s' % (v, v)
                for v in self.record_variables]
        code = '\n'.join(code)

        CodeRunner.__init__(self, group=self, template='statemonitor',
                            code=code, name=name,
                            when=scheduler,
                            check_units=False)

        # Setup variables
        self.variables = Variables(self)

        self.variables.add_dynamic_array('t', size=0, unit=second,
                                         constant=False, constant_size=False)
        if scheduler.clock is source.clock:
            self.variables.add_reference('_clock_t', source.variables['t'])
        else:
            self.variables.add_attribute_variable('_clock_t', unit=second,
                                                  obj=scheduler.clock,
                                                  attribute='t_')
        self.variables.add_attribute_variable('N', unit=Unit(1),
                                              dtype=np.int32,
                                              obj=self, attribute='_N')
        self.variables.add_array('_indices', size=len(self.indices),
                                 unit=Unit(1), dtype=self.indices.dtype,
                                 constant=True, read_only=True)
        self.variables['_indices'].set_value(self.indices)

        for varname in variables:
            var = source.variables[varname]
            if var.scalar and len(self.indices) > 1:
                logger.warn(('Variable %s is a scalar variable but it will be '
                             'recorded once for every target.' % varname),
                            once=True)
            index = source.variables.indices[varname]
            self.variables.add_reference(varname, var,
                                         index=index)
            if not index in ('_idx', '0') and index not in variables:
                self.variables.add_reference(index, source.variables[index])
            # For subexpressions, we also need all referred variables (if they
            # are not already present, e.g. the t as _clock_t
            if isinstance(var, Subexpression):
                for subexpr_varname in var.identifiers:
                    if subexpr_varname in source.variables:
                        source_var = source.variables[subexpr_varname]
                        index = source.variables.indices[subexpr_varname]
                        if index != '_idx' and index not in variables:
                            self.variables.add_reference(index,
                                                         source.variables[index])
                        if not source_var in self.variables.values():
                            source_index = source.variables.indices[subexpr_varname]
                            # `translate_subexpression` will later replace
                            # the name used in the original subexpression with
                            # _source_varname
                            self.variables.add_reference('_source_'+subexpr_varname,
                                                         source_var,
                                                         index=source_index)
            self.variables.add_dynamic_array('_recorded_' + varname,
                                             size=(0, len(self.indices)),
                                             unit=var.unit,
                                             dtype=var.dtype,
                                             constant=False,
                                             constant_size=False)

        for varname in self.record_variables:
            var = self.source.variables[varname]
            self.variables.add_auxiliary_variable('_to_record_' + varname,
                                                  unit=var.unit,
                                                  dtype=var.dtype,
                                                  scalar=var.scalar)

        self.recorded_variables = dict([(varname,
                                         self.variables['_recorded_'+varname])
                                        for varname in self.record_variables])
        recorded_names = ['_recorded_'+varname
                          for varname in self.record_variables]

        self.needed_variables = recorded_names
        self.template_kwds = template_kwds={'_recorded_variables':
                                            self.recorded_variables}
        self._N = 0
        self._enable_group_attributes()