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]
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
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]
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]