Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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