def validate_processes(self): while self.status == "LOADING": pass state_names = set([x.name for x in self.states]) for name, p in self.processes.items(): for x in p.transitions: if x.initial_state: if not x.initial_state in state_names: log.ERROR( "Process " + p.name + " is invalid. Transition from state that does not exist: " + str(x.initial_state), self.identity) if x.final_state: if not x.final_state in state_names: log.ERROR( "Process " + p.name + " is invalid. Transition to state that does not exist: " + str(x.final_state), self.identity) #Now convert states into dict for fast lookup sd = {} for s in self.states: sd[s.name] = s self.states = sd self.send(self.parent, "TASK_COMPLETE")
def parse_states(self): with open(self.configs["states_location"], 'r') as f: current_state = {} for line in f: #TODO: currently this chokes on consecutive blank lines, fix it to enable any number of blank lines if not line.strip(): if current_state["name"] in self.states: log.ERROR( "Duplicate state name '" + current_state["name"] + "'. All state names must be unique. Only the first entry will be kept.", self.identity) current_state = {} else: self.states[current_state["name"]] = copy.deepcopy( current_state) current_state = {} else: current_state = self.get_kv(current_state, line) #needed to commit the last state to memory self.states[current_state["name"]] = copy.deepcopy(current_state) log.INFO( "Successfully loaded states from " + self.configs["states_location"], self.identity) self.send(self.parent, "TASK_COMPLETE")
def check_numeric(x): try: if isinstance(x, float): return float(x) return int(x) except: log.ERROR("Invalid numeric: " + str(x))
def process_event(self, event): #track which systems are processing events and which have finished #pass the event to the relevant system #print(str(event)) if event.event_type == "SimStart": log.EVENT(event) if self.status == "WAITING": self.system_finished("") return if event.event_type == "SimEnd": while self.active_systems: log.INFO( "...Waiting on " + str(self.active_systems) + " to finish processing.", self.identity) for sys in self.active_systems: self.send(sys, "check_status") time.sleep(1) log.EVENT(event) self.send(self.parent, "TASK_COMPLETE") return try: sys = event_sys[event.event_type] if not sys in self.active_systems: #print(sys + " STARTED at time " +str(event.time)) self.active_systems.add(sys) self.send(getattr(self, sys), ('event', event)) except: log.ERROR("Unrecognized event type: " + str(event.event_type), self.identity)
def __init__(self,data): if len(data) > 4: log.ERROR("Invalid transition in process file: " +str(data)+" new transition") self.xtype = None self.initial_state = None self.final_state = None self.message = None self.prob = None self.parse_data(data)
def receiveMessage(self, message, sender): if message=="init": self.parent = sender self.load_configs("input_files/Sim.config") elif message[-1]=="=": try: self.handle_key_request(sender,message[:-1]) except: log.ERROR("Bad key request from {0} Key not specified in configs: {1} ".format( str(sender),message[:-1]),self.identity)
def load_name(self, name_data): for line in name_data.split('\n'): n = line.strip().lower()[:4] if n in ["area", "site", "name"]: split_point = line.find(":") self.name = line[split_point + 1:].strip() return log.ERROR( "Invalid KML entry, name not found in description tag " + str(name_data), "new_area")
def handle_state_change(self, event): p = event.source.process sname = p.get_next_state(event.source.state) if not sname: log.ERROR( "No valid state transition detected for state: " + str(event.source.state.name) + " in process: " + str(p.name), self.identity) self.current_events.discard(event) self.check_events_finished() return speed1 = event.source.state.speed speed2 = self.states[sname].speed s1 = event.source.state s2 = self.states[sname] event.source.state = s2 self.send(self.entity_system, ("update_entity_state", (event, event.source))) recalc_tta = bool( s1.speed != s2.speed) #we need to recalc TTA IFF speed or destination change #Directives go straight into the event queue and are not tracked #as part of processing for the current time step until they are #removed from queue if getattr(s2, "directives", None): #give the main event loop a heads up that we will be activating an additional system for d in s2.directives: d.time = event.time d.source = event.source if d.event_type == "GoTo": self.send(self.main_event_loop, ("activating_system", "geometry_system")) recalc_tta = False self.send(self.event_system, ("add_event", d)) if recalc_tta: self.alert_recalc_TTA(event) #self.process_directives(event) ###GoTo directive gets added to the stack and passed to the geometry system when processed ##The geometry system will calculate TTA and schedule an arrival event ##in addition, the geometry system tracks the original arrival events so that ##they can be deleted from queue as necessary #if an entity is in transit and its speed changes, the geometry system needs to remove old event #and schedule new event #if the state does not have an indefinite duration, #then schedule the next state if event.source.state.duration.min != -1: self.schedule_state_change(event, event.source) else: self.current_events.discard(event) self.check_events_finished()
def validate_time(data): return_data = None try: return_data = int(data) except: if not runtime_utils.start_time: reload(runtime_utils) abs_event_time = runtime_utils.unix_time_millis(parse(data)) return_data = int(abs_event_time - runtime_utils.start_time) try: if return_data < runtime_utils.current_time: log.ERROR( "Causality error - Events cannot be scheduled prior to sim time: " + str(data)) #throw error if time is before the current time. Backscheduling is not allowed. except: pass return return_data
def parse_process(self): with open(self.configs["process_location"], 'r') as f: current_process = {} for line in f: if line: current_process = self.get_kv(current_process, line) else: if current_process["name"] in self.processes: log.ERROR( "Duplicate process name '" + current_process["name"] + "'. All process names must be unique. Only the first entry will be kept.", self.identity) else: self.processes[current_process[ "name"]] = copy.deepcopy(current_process) current_process = {} #needed to commit the last process to memory self.processes[current_process["name"]] = copy.deepcopy( current_process) log.INFO( "Successfully loaded processes from " + self.configs["process_location"], self.identity) self.send(self.parent, "TASK_COMPLETE")
def validate_source(source): if isinstance(source, entities.Entity) or isinstance( source, Area) or str(source) == "SYSTEM": return source log.ERROR("Bad event generated: " + str(source) + " is not a valid event source.")
def validate(obj, REQUIRED_KEYS): for key in REQUIRED_KEYS: if not hasattr(obj, key): log.ERROR("Missing required key '" + key + "' for new state", "new state")