def __run(self, model, curr_state, total_time, timeline, trajectory_base, live_grapher, t=20, number_of_trajectories=1, increment=0.05, seed=None, debug=False, profile=False, timeout=None, resume=None, tau_tol=0.03, **kwargs): # for use with resume, determines how much excess data to cut off due to # how species and time are initialized to 0 timeStopped = 0 if resume is not None: if resume[0].model != model: raise ModelError( 'When resuming, one must not alter the model being resumed.' ) if t < resume['time'][-1]: raise ExecutionError( "'t' must be greater than previous simulations end time, or set in the run() method as the " "simulations next end time") if debug: print("t = ", t) print("increment = ", increment) species_mappings, species, parameter_mappings, number_species = nputils.numpy_initialization( model) # create numpy matrix to mark all state data of time and species trajectory_base, tmpSpecies = nputils.numpy_trajectory_base_initialization( model, number_of_trajectories, timeline, species, resume=resume) if seed is not None: if not isinstance(seed, int): seed = int(seed) if seed > 0: random.seed(seed) np.random.seed(seed) else: raise ModelError('seed must be a positive integer') simulation_data = [] for trajectory_num in range(number_of_trajectories): if self.stop_event.is_set(): self.rc = 33 break elif self.pause_event.is_set(): timeStopped = timeline[entry_count] # For multi trajectories, live_grapher needs to be informed of trajectory increment if live_grapher[0] is not None: live_grapher[0].increment_trajectory(trajectory_num) start_state = [0] * (len(model.listOfReactions) + len(model.listOfRateRules)) propensities = {} curr_state[0] = {} if resume is not None: save_time = total_time[0] curr_time = [save_time] else: save_time = 0 curr_time = [0] curr_state[0]['vol'] = model.volume data = {'time': timeline} steps_taken = [] steps_rejected = 0 entry_count = 0 trajectory = trajectory_base[trajectory_num] HOR, reactants, mu_i, sigma_i, g_i, epsilon_i, critical_threshold = Tau.initialize( model, tau_tol) # initialize populations if not (resume is None): for spec in model.listOfSpecies: curr_state[0][spec] = tmpSpecies[spec] else: for spec in model.listOfSpecies: curr_state[0][spec] = model.listOfSpecies[ spec].initial_value for param in model.listOfParameters: curr_state[0][param] = model.listOfParameters[param].value for i, rxn in enumerate(model.listOfReactions): # set reactions to uniform random number and add to start_state start_state[i] = (math.log(random.uniform(0, 1))) if debug: print("Setting Random number ", start_state[i], " for ", model.listOfReactions[rxn].name) compiled_propensities = {} for i, r in enumerate(model.listOfReactions): compiled_propensities[r] = compile( model.listOfReactions[r].propensity_function, '<string>', 'eval') timestep = 0 # Each save step while entry_count < timeline.size: if self.stop_event.is_set(): self.rc = 33 break elif self.pause_event.is_set(): timeStopped = timeline[entry_count] break # Until save step reached while curr_time[0] < save_time: if self.stop_event.is_set(): self.rc = 33 break elif self.pause_event.is_set(): timeStopped = timeline[entry_count] break propensity_sum = 0 for i, r in enumerate(model.listOfReactions): propensities[r] = eval(compiled_propensities[r], curr_state[0]) propensity_sum += propensities[r] tau_args = [ HOR, reactants, mu_i, sigma_i, g_i, epsilon_i, tau_tol, critical_threshold, model, propensities, curr_state[0], curr_time[0], save_time ] tau_step = Tau.select(*tau_args) prev_start_state = start_state.copy() prev_curr_state = curr_state[0].copy() prev_curr_time = curr_time[0] loop_cnt = 0 while True: loop_cnt += 1 if loop_cnt > 100: raise Exception( "Loop over __get_reactions() exceeded loop count" ) reactions, curr_state[0], curr_time[ 0] = self.__get_reactions(tau_step, curr_state[0], curr_time[0], save_time, propensities, model.listOfReactions) # Update curr_state with the result of the SSA reaction that fired species_modified = {} for i, rxn in enumerate(model.listOfReactions): if reactions[rxn] > 0: for reactant in model.listOfReactions[ rxn].reactants: species_modified[reactant.name] = True curr_state[0][ reactant. name] -= model.listOfReactions[ rxn].reactants[ reactant] * reactions[rxn] for product in model.listOfReactions[ rxn].products: species_modified[product.name] = True curr_state[0][ product.name] += model.listOfReactions[ rxn].products[product] * reactions[ rxn] neg_state = False for spec in species_modified: if curr_state[0][spec] < 0: neg_state = True if debug: print( "Negative state detected: curr_state[{0}]= {1}" .format(spec, curr_state[0][spec])) if neg_state: if debug: print("\trxn={0}".format(reactions)) start_state = prev_start_state.copy() curr_state[0] = prev_curr_state.copy() curr_time[0] = prev_curr_time total_time[0] = prev_curr_time tau_step = tau_step / 2 steps_rejected += 1 if debug: print("Resetting curr_state[{0}]= {1}".format( spec, curr_state[0][spec])) if debug: print( "\tRejecting step, taking step of half size, tau_step={0}" .format(tau_step)) else: break # breakout of the while True # save step reached for i in range(number_species): trajectory[entry_count][i + 1] = curr_state[0][species[i]] save_time += increment timestep += 1 entry_count += 1 # end of trajectory for i in range(number_species): data[species[i]] = trajectory[:, i + 1] simulation_data.append(data) if profile: print(steps_taken) print("Total Steps Taken: ", len(steps_taken)) print("Total Steps Rejected: ", steps_rejected) # If simulation has been paused, or tstopped !=0 if timeStopped != 0 or resume is not None: simulation_data = nputils.numpy_resume(timeStopped, simulation_data, resume=resume) self.result = simulation_data return self.result, self.rc
def __run(self, model, curr_state, total_time, timeline, trajectory_base, live_grapher, t=20, number_of_trajectories=1, increment=0.05, seed=None, debug=False, show_labels=True, resume=None, timeout=None): # for use with resume, determines how much excess data to cut off due to # how species and time are initialized to 0 timeStopped = 0 if resume is not None: if resume[0].model != model: raise gillespyError.ModelError( 'When resuming, one must not alter the model being resumed.' ) if t < resume['time'][-1]: raise gillespyError.ExecutionError( "'t' must be greater than previous simulations end time, or set in the run() method as the " "simulations next end time") random.seed(seed) species_mappings, species, parameter_mappings, number_species = nputils.numpy_initialization( model) # create dictionary of all constant parameters for propensity evaluation parameters = {'V': model.volume} for paramName, param in model.listOfParameters.items(): parameters[parameter_mappings[paramName]] = param.value # create mapping of reaction dictionary to array indices reactions = list(model.listOfReactions.keys()) # create mapping of reactions, and which reactions depend on their reactants/products dependent_rxns = nputils.dependency_grapher(model, reactions) number_reactions = len(reactions) propensity_functions = {} # create an array mapping reactions to species modified species_changes = np.zeros((number_reactions, number_species)) # pre-evaluate propensity equations from strings: for i, reaction in enumerate(reactions): # replace all references to species with array indices for j, spec in enumerate(species): species_changes[i][j] = model.listOfReactions[reaction].products.get(model.listOfSpecies[spec], 0) \ - model.listOfReactions[reaction].reactants.get(model.listOfSpecies[spec], 0) if debug: print('species_changes: {0},i={1}, j={2}... {3}'.format( species, i, j, species_changes[i][j])) propensity_functions[reaction] = [ eval( 'lambda S:' + model. listOfReactions[reaction].sanitized_propensity_function( species_mappings, parameter_mappings), parameters), i ] if debug: print('propensity_functions', propensity_functions) # begin simulating each trajectory simulation_data = [] for trajectory_num in range(number_of_trajectories): total_time[0] = 0 if self.stop_event.is_set(): self.rc = 33 break elif self.pause_event.is_set(): timeStopped = timeline[entry_count] break # For multi trajectories, live_grapher needs to be informed of trajectory increment if live_grapher[0] is not None: live_grapher[0].increment_trajectory(trajectory_num) # copy initial state data trajectory = trajectory_base[trajectory_num] entry_count = 1 curr_state[0] = {} # curr_time and curr_state are list of len 1 so that __run receives reference if resume is not None: curr_time = [resume['time'][-1]] else: curr_time = [0] for spec in model.listOfSpecies: if resume is not None: curr_state[0][spec] = resume[spec][-1] else: curr_state[0][spec] = model.listOfSpecies[ spec].initial_value propensity_sums = np.zeros(number_reactions) # calculate initial propensity sums while entry_count < timeline.size: if self.stop_event.is_set(): self.rc = 33 break elif self.pause_event.is_set(): timeStopped = timeline[entry_count] break # determine next reaction species_states = list(curr_state[0].values()) for i in range(number_reactions): propensity_sums[i] = propensity_functions[reactions[i]][0]( species_states) if debug: print('propensity: ', propensity_sums[i]) propensity_sum = np.sum(propensity_sums) if debug: print('propensity_sum: ', propensity_sum) # if no more reactions, quit if propensity_sum <= 0: trajectory[entry_count:, 1:] = list(species_states) break cumulative_sum = random.uniform(0, propensity_sum) curr_time[0] += -math.log(random.random()) / propensity_sum total_time[0] += -math.log(random.random()) / propensity_sum if debug: print('cumulative sum: ', cumulative_sum) print('entry count: ', entry_count) print('timeline.size: ', timeline.size) print('curr_time: ', curr_time[0]) # determine time passed in this reaction while entry_count < timeline.size and timeline[ entry_count] <= curr_time[0]: if self.stop_event.is_set(): self.rc = 33 break elif self.pause_event.is_set(): timeStopped = timeline[entry_count] break trajectory[entry_count, 1:] = species_states entry_count += 1 for potential_reaction in range(number_reactions): cumulative_sum -= propensity_sums[potential_reaction] if debug: print('if <=0, fire: ', cumulative_sum) if cumulative_sum <= 0: for i, spec in enumerate(model.listOfSpecies): curr_state[0][spec] += species_changes[ potential_reaction][i] reacName = reactions[potential_reaction] if debug: print('current state: ', curr_state[0]) print('species_changes: ', species_changes) print('updating: ', potential_reaction) species_states = list(curr_state[0].values()) for i in dependent_rxns[reacName]['dependencies']: propensity_sums[propensity_functions[i] [1]] = propensity_functions[i][0]( species_states) if debug: print('new propensity sum: ', propensity_sums[i]) break data = {'time': timeline} for i in range(number_species): data[species[i]] = trajectory[:, i + 1] simulation_data.append(data) # If simulation has been paused, or tstopped !=0 if timeStopped != 0 or resume is not None: simulation_data = nputils.numpy_resume(timeStopped, simulation_data, resume=resume) self.result = simulation_data return self.result, self.rc
def __run(self, curr_state, curr_time, timeline, trajectory_base, tmpSpecies, live_grapher, t=20, number_of_trajectories=1, increment=0.05, integrator='lsoda', integrator_options={}, resume=None, **kwargs): timeStopped = 0 if resume is not None: if resume[0].model != self.model: raise gillespyError.ModelError('When resuming, one must not alter the model being resumed.') if t < resume['time'][-1]: raise gillespyError.ExecutionError( "'t' must be greater than previous simulations end time, or set in the run() method as the " "simulations next end time") # compile reaction propensity functions for eval c_prop = OrderedDict() for r_name, reaction in self.model.listOfReactions.items(): c_prop[r_name] = compile(reaction.ode_propensity_function, '<string>', 'eval') result = trajectory_base[0] entry_count = 0 y0 = [0] * len(self.model.listOfSpecies) curr_state[0] = OrderedDict() if resume is not None: for i, s in enumerate(tmpSpecies): curr_state[0][s] = tmpSpecies[s] y0[i] = tmpSpecies[s] else: for i, s in enumerate(self.model.listOfSpecies.values()): curr_state[0][s.name] = s.initial_value y0[i] = s.initial_value for p_name, param in self.model.listOfParameters.items(): curr_state[0][p_name] = param.value if 'vol' not in curr_state[0]: curr_state[0]['vol'] = 1.0 rhs = ode(ODESolver.__f).set_integrator(integrator, **integrator_options) rhs.set_initial_value(y0, curr_time[0]).set_f_params(curr_state, self.model, c_prop) while entry_count < timeline.size - 1: if self.stop_event.is_set(): self.rc = 33 break if self.pause_event.is_set(): timeStopped = timeline[entry_count] break int_time = curr_time[0] + increment entry_count += 1 y0 = rhs.integrate(int_time) curr_time[0] += increment for i, spec in enumerate(self.model.listOfSpecies): curr_state[0][spec] = y0[i] result[entry_count][i+1] = curr_state[0][spec] results_as_dict = { 'time': timeline } for i, species in enumerate(self.model.listOfSpecies): results_as_dict[species] = result[:, i+1] results = [results_as_dict] * number_of_trajectories if timeStopped != 0 or resume is not None: results = nputils.numpy_resume(timeStopped, results, resume=resume) self.result = results return results, self.rc