Пример #1
0
class Runnable(Reflective):
    uid_count = 0

    def __init__(self, id_, component, parent = None):
        Reflective.__init__(self)

        self.uid = Runnable.uid_count
        Runnable.uid_count += 1

        self.id = id_
        self.component = component
        self.parent = parent

        self.time_step = 0
        self.time_completed = 0
        self.time_total = 0

        self.plastic = True

        self.state_stack = Stack()

        self.children = {}
        self.uchildren = {}

        self.recorded_variables = []

        self.event_out_ports = []
        self.event_in_ports = []

        self.event_out_callbacks = {}
        self.event_in_counters = {}

        self.attachments = {}

        self.new_regime = ''
        self.current_regime = ''
        self.last_regime = ''
        self.regimes = {}

    def add_child(self, id_, runnable):
        self.uchildren[runnable.uid] = runnable
        
        self.children[id_] = runnable
        self.children[runnable.id] = runnable

        self.__dict__[id_] = runnable
        self.__dict__[runnable.id] = runnable

        runnable.configure_time(self.time_step, self.time_total)

    def add_child_to_group(self, group_name, child):
        if group_name not in self.__dict__:
            self.__dict__[group_name] = []
        self.__dict__[group_name].append(child)

    def make_attachment(self, type_, name):
        self.attachments[type_] = name
        self.__dict__[name] = []

    def add_attachment(self, runnable):
        component_type = runnable.component.context.lookup_component_type(
            runnable.component.component_type)

        for ctype in component_type.types:
            if ctype in self.attachments:
                name = self.attachments[ctype]
                runnable.id = runnable.id + str(len(self.__dict__[name]))
                self.__dict__[name].append(runnable)

                return

        raise SimBuildError('Unable to find appropriate attachment')

    def add_event_in_port(self, port):
        self.event_in_ports.append(port)
        if port not in self.event_in_counters:
            self.event_in_counters[port] = 0

    def inc_event_in(self, port):
        self.event_in_counters[port] += 1

    def add_event_out_port(self, port):
        self.event_out_ports.append(port)
        if port not in self.event_out_callbacks:
            self.event_out_callbacks[port] = []

    def register_event_out_link(self, port, runnable, remote_port):
        self.event_out_callbacks[port].append((runnable, remote_port))

    def register_event_out_callback(self, port, callback):
        if port in self.event_out_callbacks:
            self.event_out_callbacks[port].append(callback)
        else:
            raise SimBuildError('No event out port \'{0}\' in '
                                'component \'{1}\''.format(port, self.id))

    def add_regime(self, regime):
        self.regimes[regime.name] = regime

    def resolve_path(self, path):
        if path == '':
            return self
        if path[0] == '/':
            return self.parent.resolve_path(path)
        elif path.find('../') == 0:
            return self.parent.resolve_path(path[3:])
        elif path.find('..') == 0:
            return self.parent
        else:
            if path.find('/') >= 1:
                (child, new_path) = path.split('/', 1)
            else:
                child = path
                new_path = ''

            idxbegin = child.find('[')
            idxend = child.find(']')
            if idxbegin != 0 and idxend > idxbegin:
                idx = int(child[idxbegin+1:idxend])
                child = child[:idxbegin]
            else:
                idx = -1

            if child in self.children:
                childobj = self.children[child]
                if idx != -1:
                    childobj = childobj.array[idx]
            elif child in self.component.context.parameters:
                ctx = self.component.context
                p = ctx.parameters[child]
                return self.resolve_path('../' + p.value)
            else:
                raise SimBuildError('Unable to find child \'{0}\' in '
                                    '\'{1}\''.format(child, self.id))

            if new_path == '':
                return childobj
            else:
                return childobj.resolve_path(new_path)

    def add_variable_recorder(self, data_output, recorder):
        self.add_variable_recorder2(data_output, recorder, recorder.quantity)

    def add_variable_recorder2(self, data_output, recorder, path):
        if path[0] == '/':
            self.parent.add_variable_recorder2(data_output, recorder, path)
        elif path.find('../') == 0:
            self.parent.add_variable_recorder2(data_output, recorder, path[3:])
        elif path.find('/') >= 1:
            (child, new_path) = path.split('/', 1)

            idxbegin = child.find('[')
            idxend = child.find(']')
            if idxbegin != 0 and idxend > idxbegin:
                idx = int(child[idxbegin+1:idxend])
                child = child[:idxbegin]
            else:
                idx = -1

            if child in self.children:
                childobj = self.children[child]
                if idx == -1:
                    childobj.add_variable_recorder2(data_output,
                                                    recorder,
                                                    new_path)
                else:
                    childobj.array[idx].add_variable_recorder2(data_output,
                                                               recorder,
                                                               new_path)
            else:
                raise SimBuildError('Unable to find child \'{0}\' in '
                                    '\'{1}\''.format(child, self.id))
        else:
            self.recorded_variables.append(Recording(path, data_output, recorder))


    def configure_time(self, time_step, time_total):
        self.time_step = time_step
        self.time_total = time_total

        for cn in self.uchildren:
            self.uchildren[cn].configure_time(self.time_step, self.time_total)

        for c in self.array:
            c.configure_time(self.time_step, self.time_total)

        ## for type_ in self.attachments:
        ##     components = self.__dict__[self.attachments[type_]]
        ##     for component in components:
        ##         component.configure_time(self.time_step, self.time_total)


    def reset_time(self):
        self.time_completed = 0

        for cid in self.uchildren:
            self.uchildren[cid].reset_time()

        for c in self.array:
            c.reset_time()

        ## for type_ in self.attachments:
        ##     components = self.__dict__[self.attachments[type_]]
        ##     for component in components:
        ##         component.reset_time()

    def single_step(self, dt):
        #return self.single_step2(dt)

        # For debugging
        try:
            return self.single_step2(dt)
        #except Ex1 as e:
        #    print self.rate
        #    print self.midpoint
        #    print self.scale
        #    print self.parent.parent.parent.parent.v
        #    # rate * exp((v - midpoint)/scale)
        #    sys.exit(0)
        except Exception as e:
            r = self
            name = r.id
            while r.parent:
                r = r.parent
                name = "{0}.{1}".format(r.id, name)

            print("Error in '{0} ({2})': {1}".format(name, e,
                                                     self.component.component_type))
            print(type(e))
            keys = self.__dict__.keys()
            keys.sort()
            for k in keys:
                print('{0} -> {1}'.format(k, self.__dict__[k]))
            print('')
            print('')

            if isinstance(e, ArithmeticError):
                print(('This is an arithmetic error. Consider reducing the '
                       'integration time step.'))

            sys.exit(0)

    def single_step2(self, dt):
        for cid in self.uchildren:
            self.uchildren[cid].single_step(dt)

        for child in self.array:
            child.single_step(dt)

        ## for type_ in self.attachments:
        ##     components = self.__dict__[self.attachments[type_]]
        ##     for component in components:
        ##         component.single_step(dt)

        if self.new_regime != '':
            self.current_regime = self.new_regime
            self.new_regime = ''

        self.update_kinetic_scheme(self, dt)

        if self.time_completed == 0:
            self.run_startup_event_handlers(self)

        self.run_preprocessing_event_handlers(self)
        self.update_shadow_variables()

        self.update_derived_variables(self)
        self.update_shadow_variables()

        self.update_state_variables(self, dt)
        self.update_shadow_variables()

        self.run_postprocessing_event_handlers(self)
        self.update_shadow_variables()

        if self.current_regime != '':
            regime = self.regimes[self.current_regime]

            regime.update_kinetic_scheme(self, dt)

            #if self.time_completed == 0:
            #    self.run_startup_event_handlers(self)

            regime.run_preprocessing_event_handlers(self)
            self.update_shadow_variables()

            regime.update_derived_variables(self)
            self.update_shadow_variables()

            regime.update_state_variables(self, dt)
            self.update_shadow_variables()

            regime.run_postprocessing_event_handlers(self)
            self.update_shadow_variables()

        self.record_variables()

        self.time_completed += dt
        if self.time_completed >= self.time_total:
            return 0
        else:
            return dt


    def record_variables(self):
        for recording in self.recorded_variables:
            recording.add_value(self.time_completed,
                               self.__dict__[recording.variable])

    def push_state(self):
        vars = []
        for varname in self.instance_variables:
            vars += [self.__dict__[varname],
                     self.__dict__[varname + '_shadow']]
        self.state_stack.push(vars)

        for cid in self.uchildren:
            self.uchildren[cid].push_state()

        for c in self.array:
            c.push_state()

    def pop_state(self):
        vars = self.state_stack.pop()
        for varname in self.instance_variables:
            self.__dict_[varname] = vars[0]
            self.__dict_[varname + '_shadow'] = vars[1]
            vars = vars[2:]

        for cid in self.uchildren:
            self.uchildren[cid].pop_state()

        for c in self.array:
            c.pop_state()

    def update_shadow_variables(self):
        if self.plastic:
            for var in self.instance_variables:
                self.__dict__[var + '_shadow'] = self.__dict__[var]
            for var in self.derived_variables:
                self.__dict__[var + '_shadow'] = self.__dict__[var]
Пример #2
0
    def parse_token_list_rec(self):
        """
        Parses a tokenized arithmetic expression into a parse tree. It calls
        itself recursively to handle bracketed subexpressions.

        @return: Returns a token string.
        @rtype: lems.parser.expr.ExprNode

        @attention: Does not handle unary minuses at the moment. Needs to be
        fixed.
        """
        
        op_stack = Stack()
        val_stack = Stack()
        node_stack = Stack()
        
        op_stack.push('$')
        val_stack.push('$')

        exit_loop = False

        while self.token_list and not exit_loop:
            token = self.token_list[0]
            self.token_list = self.token_list[1:]
            
            #print '###> ', token,op_stack,node_stack,val_stack
            
            if token == '(':
                node_stack.push(self.parse_token_list_rec())
                val_stack.push('$')
            elif self.is_func(token):
                op_stack.push(token)
            elif self.is_op(token):
                if self.op_priority[op_stack.top()] >= \
                       self.op_priority[token]:

                    op = op_stack.pop()
                    if self.is_func(op):
                        rval = val_stack.pop()
                        if rval == '$':
                            right = node_stack.pop()
                        else:
                            right = ValueNode(rval)
                
                        node_stack.push(Func1Node(op, right))
                        val_stack.push('$')
                    elif op == '~':
                        rval = val_stack.pop()

                        if rval == '$':
                            right = node_stack.pop()
                        else:
                            right = ValueNode(rval)
                
                        node_stack.push(OpNode('-', ValueNode('0'), right))
                        val_stack.push('$')
                    else:
                        rval = val_stack.pop()
                        lval = val_stack.pop()
                        
                        if lval == '$':
                            left = node_stack.pop()
                        else:
                            left = ValueNode(lval)

                        if rval == '$':
                            right = node_stack.pop()
                        else:
                            right = ValueNode(rval)
                
                        node_stack.push(OpNode(op, left, right))
                        val_stack.push('$')
                    
                op_stack.push(token)
            elif token == ')':
                exit_loop = True
            else:
                val_stack.push(token)
                
        rval = val_stack.pop()
        if rval == '$':
            right = node_stack.pop()
        else:
            right = ValueNode(rval)

        while op_stack.top() != '$':
            op = op_stack.pop()

            if self.is_func(op):
                right = Func1Node(op, right)
            elif op == '~':
                lval = val_stack.pop()

                right = OpNode('-', ValueNode('0'), right)
            else:
                lval = val_stack.pop()
                if lval == '$':
                    if node_stack.is_empty():
                        left = ValueNode('0')
                    else:
                        left = node_stack.pop()
                else:
                    left = ValueNode(lval)

                right = OpNode(op, left, right)
                
        return right
Пример #3
0
class Runnable(Reflective):
    def __init__(self, id, parent=None):
        Reflective.__init__(self)

        self.id = id
        self.parent = parent

        self.time_step = 0
        self.time_completed = 0
        self.time_total = 0

        self.plastic = True

        self.state_stack = Stack()

        self.children = {}

        self.recorded_variables = {}

        self.event_out_callbacks = {}
        self.event_in_counters = {}

    def add_child(self, id, runnable):
        self.children[id] = runnable
        runnable.configure_time(self.time_step, self.time_total)

    def add_event_in_port(self, port):
        if port not in self.event_in_counters:
            self.event_in_counters[port] = 0

    def inc_event_in(self, port):
        self.event_in_counters[port] += 1

    def add_event_out_port(self, port):
        if port not in self.event_out_callbacks:
            self.event_out_callbacks[port] = []

    def register_event_out_link(self, port, runnable, remote_port):
        self.event_out_callbacks[port].append((runnable, remote_port))

    def register_event_out_callback(self, port, callback):
        if port in self.event_out_callbacks:
            self.event_out_callbacks[port].append(callback)
        else:
            raise SimBuildError('No event out port \'{0}\' in '
                                'component \'{1}\''.format(port, self.name))

    def add_variable_recorder(self, path):
        if path[0] == '/':
            self.parent.add_variable_recorder(path)
        elif path.find('../') == 0:
            self.parent.add_variable_recorder(path[3:])
        elif path.find('/') >= 1:
            (child, new_path) = path.split('/', 1)

            idxbegin = child.find('[')
            idxend = child.find(']')
            if idxbegin != 0 and idxend > idxbegin:
                idx = int(child[idxbegin + 1:idxend])
                child = child[:idxbegin]
            else:
                idx = -1

            if child in self.children:
                childobj = self.children[child]
                if idx == -1:
                    childobj.add_variable_recorder(new_path)
                else:
                    childobj.array[idx].add_variable_recorder(new_path)
            else:
                raise SimBuildError('Unable to find child \'{0}\' in '
                                    '\'{1}\''.format(child, self.id))
        else:
            self.recorded_variables[path] = []

    def configure_time(self, time_step, time_total):
        self.time_step = time_step
        self.time_total = time_total

        for cn in self.children:
            self.children[cn].configure_time(self.time_step, self.time_total)

    def reset_time(self):
        self.time_completed = 0

        for cid in self.children:
            self.children[cid].reset_time()

    def single_step(self, dt):
        # For debugging
        try:
            return self.single_step2(dt)
        except Exception as e:
            r = self
            name = r.id
            while r.parent:
                name = "{0}.{1}".format(r.id, name)
                r = r.parent

            print "Error in '{0}': {1}".format(name, e)
            sys.exit(0)

    def single_step2(self, dt):
        #print 'Single stepping {0}'.format(self.id)

        self.run_preprocessing_event_handlers(self)
        self.update_shadow_variables()

        self.update_state_variables(self, dt)
        self.update_shadow_variables()

        self.run_postprocessing_event_handlers(self)
        self.update_shadow_variables()

        self.record_variables()

        for cid in self.children:
            self.children[cid].single_step(dt)

        self.time_completed += self.time_step
        if self.time_completed >= self.time_total:
            return 0
        else:
            return self.time_step

    def record_variables(self):
        for variable in self.recorded_variables:
            self.recorded_variables[variable].append(\
                (self.time_completed, self.__dict__[variable]))
            #print self.id
            #print self.time_completed, self.__dict__[variable]

    def push_state(self):
        vars = []
        for varname in self.instance_variables:
            vars += [
                self.__dict__[varname], self.__dict__[varname + '_shadow']
            ]
        self.state_stack.push(vars)

        for cid in self.children:
            self.children[cid].push_state()

    def pop_state(self):
        vars = self.state_stack.pop()
        for varname in self.instance_variables:
            self.__dict_[varname] = vars[0]
            self.__dict_[varname + '_shadow'] = vars[1]
            vars = vars[2:]

        for cid in self.children:
            self.children[cid].pop_state()

    def update_shadow_variables(self):
        if self.plastic:
            for var in self.instance_variables:
                self.__dict__[var + '_shadow'] = self.__dict__[var]
Пример #4
0
    def parse_token_list_rec(self):
        """
        Parses a tokenized arithmetic expression into a parse tree. It calls
        itself recursively to handle bracketed subexpressions.

        @return: Returns a token string.
        @rtype: lems.parser.expr.ExprNode

        @attention: Does not handle unary minuses at the moment. Needs to be
        fixed.
        """

        op_stack = Stack()
        val_stack = Stack()
        node_stack = Stack()

        op_stack.push('$')
        val_stack.push('$')

        exit_loop = False

        while self.token_list and not exit_loop:
            token = self.token_list[0]
            self.token_list = self.token_list[1:]

            #print '###> ', token,op_stack,node_stack,val_stack

            if token == '(':
                node_stack.push(self.parse_token_list_rec())
                val_stack.push('$')
            elif self.is_func(token):
                op_stack.push(token)
            elif self.is_op(token):
                if self.op_priority[op_stack.top()] >= \
                       self.op_priority[token]:

                    op = op_stack.pop()
                    if self.is_func(op):
                        rval = val_stack.pop()
                        if rval == '$':
                            right = node_stack.pop()
                        else:
                            right = ValueNode(rval)

                        node_stack.push(Func1Node(op, right))
                        val_stack.push('$')
                    elif op == '~':
                        rval = val_stack.pop()

                        if rval == '$':
                            right = node_stack.pop()
                        else:
                            right = ValueNode(rval)

                        node_stack.push(OpNode('-', ValueNode('0'), right))
                        val_stack.push('$')
                    else:
                        rval = val_stack.pop()
                        lval = val_stack.pop()

                        if lval == '$':
                            left = node_stack.pop()
                        else:
                            left = ValueNode(lval)

                        if rval == '$':
                            right = node_stack.pop()
                        else:
                            right = ValueNode(rval)

                        node_stack.push(OpNode(op, left, right))
                        val_stack.push('$')

                op_stack.push(token)
            elif token == ')':
                exit_loop = True
            else:
                val_stack.push(token)

        rval = val_stack.pop()
        if rval == '$':
            right = node_stack.pop()
        else:
            right = ValueNode(rval)

        while op_stack.top() != '$':
            op = op_stack.pop()

            if self.is_func(op):
                right = Func1Node(op, right)
            elif op == '~':
                lval = val_stack.pop()

                right = OpNode('-', ValueNode('0'), right)
            else:
                lval = val_stack.pop()
                if lval == '$':
                    if node_stack.is_empty():
                        left = ValueNode('0')
                    else:
                        left = node_stack.pop()
                else:
                    left = ValueNode(lval)

                right = OpNode(op, left, right)

        return right
Пример #5
0
class Runnable(Reflective):
    def __init__(self, id, parent = None):
        Reflective.__init__(self)

        self.id = id
        self.parent = parent
        
        self.time_step = 0
        self.time_completed = 0
        self.time_total = 0

        self.plastic = True

        self.state_stack = Stack()

        self.children = {}

        self.recorded_variables = {}

        self.event_out_callbacks = {}
        self.event_in_counters = {}

    def add_child(self, id, runnable):
        self.children[id] = runnable
        runnable.configure_time(self.time_step, self.time_total)

    def add_event_in_port(self, port):
        if port not in self.event_in_counters:
            self.event_in_counters[port] = 0

    def inc_event_in(self, port):
        self.event_in_counters[port] += 1
        
    def add_event_out_port(self, port):
        if port not in self.event_out_callbacks:
            self.event_out_callbacks[port] = []

    def register_event_out_link(self, port, runnable, remote_port):
        self.event_out_callbacks[port].append((runnable, remote_port))
        
    def register_event_out_callback(self, port, callback):
        if port in self.event_out_callbacks:
            self.event_out_callbacks[port].append(callback)
        else:
            raise SimBuildError('No event out port \'{0}\' in '
                                'component \'{1}\''.format(port, self.name))
                                    
    def add_variable_recorder(self, path):
        if path[0] == '/':
            self.parent.add_variable_recorder(path)
        elif path.find('../') == 0:
            self.parent.add_variable_recorder(path[3:])
        elif path.find('/') >= 1:
            (child, new_path) = path.split('/', 1)

            idxbegin = child.find('[')
            idxend = child.find(']')
            if idxbegin != 0 and idxend > idxbegin:
                idx = int(child[idxbegin+1:idxend])
                child = child[:idxbegin]
            else:
                idx = -1

            if child in self.children:
                childobj = self.children[child]
                if idx == -1:
                    childobj.add_variable_recorder(new_path)
                else:
                    childobj.array[idx].add_variable_recorder(new_path)
            else:
                raise SimBuildError('Unable to find child \'{0}\' in '
                                    '\'{1}\''.format(child, self.id))
        else:
            self.recorded_variables[path] = []

    def configure_time(self, time_step, time_total):
        self.time_step = time_step
        self.time_total = time_total

        for cn in self.children:
            self.children[cn].configure_time(self.time_step, self.time_total)

        
    def reset_time(self):
        self.time_completed = 0
        
        for cid in self.children:
            self.children[cid].reset_time()

    def single_step(self, dt):
        # For debugging
        try:
            return self.single_step2(dt)
        except Exception as e:
            r = self
            name = r.id
            while r.parent:
                name = "{0}.{1}".format(r.id, name)
                r = r.parent
                
            print "Error in '{0}': {1}".format(name, e)
            sys.exit(0)
            
    def single_step2(self, dt):
        #print 'Single stepping {0}'.format(self.id)
        
        self.run_preprocessing_event_handlers(self)
        self.update_shadow_variables()

        self.update_state_variables(self, dt)
        self.update_shadow_variables()

        self.run_postprocessing_event_handlers(self)
        self.update_shadow_variables()

        self.record_variables()

        for cid in self.children:
            self.children[cid].single_step(dt)

        self.time_completed += self.time_step
        if self.time_completed >= self.time_total:
            return 0
        else:
            return self.time_step

    def record_variables(self):
        for variable in self.recorded_variables:
            self.recorded_variables[variable].append(\
                (self.time_completed, self.__dict__[variable]))
            #print self.id
            #print self.time_completed, self.__dict__[variable]
            
    def push_state(self):
        vars = []
        for varname in self.instance_variables:
            vars += [self.__dict__[varname],
                     self.__dict__[varname + '_shadow']]
        self.state_stack.push(vars)

        for cid in self.children:
            self.children[cid].push_state()

    def pop_state(self):
        vars = self.state_stack.pop()
        for varname in self.instance_variables:
            self.__dict_[varname] = vars[0]
            self.__dict_[varname + '_shadow'] = vars[1]
            vars = vars[2:]

        for cid in self.children:
            self.children[cid].pop_state()

    def update_shadow_variables(self):
        if self.plastic:
            for var in self.instance_variables:
                self.__dict__[var + '_shadow'] = self.__dict__[var]