def next_update(self, timestep, states):

        # get mmol_to_counts for converting flux to exchange counts
        mmol_to_counts = states['global']['mmol_to_counts']

        # kinetic rate law requires a flat dict with ('port', 'state') keys.
        flattened_states = remove_units(tuplify_port_dicts(states))

        # get flux
        fluxes = self.kinetic_rate_laws.get_fluxes(flattened_states)

        # make the update
        # add fluxes to update
        update = {port: {} for port in self.port_ids}
        update.update({'fluxes': fluxes})

        # get exchange and update fields
        for reaction_id, flux in fluxes.items():
            stoichiometry = self.reactions[reaction_id]['stoichiometry']
            for port_state_id, coeff in stoichiometry.items():
                for port_id in self.port_ids:
                    # separate the state_id and port_id
                    if port_id in port_state_id:
                        state_id = port_state_id[1]
                        state_flux = coeff * flux * timestep

                        if port_id == 'external':
                            # convert exchange fluxes to counts with mmol_to_counts
                            delta = int((state_flux * mmol_to_counts).magnitude)
                            existing_delta = update['fields'].get(
                                state_id, {}).get('_value', 0)
                            update['fields'][state_id] = {
                                '_value': existing_delta + delta,
                                '_updater': {
                                    'updater': (
                                        'update_field_with_exchange'),
                                    'port_mapping': {
                                        'global': 'global',
                                        'dimensions': 'dimensions',
                                    },
                                },
                            }
                        else:
                            update[port_id][state_id] = (
                                update[port_id].get(state_id, 0)
                                + state_flux
                            )

        # note: external and internal ports update change in mmol.
        return update
Exemple #2
0
    def next_update(self, timestep, states):

        # get mmol_to_counts for converting flux to exchange counts
        mmol_to_counts = states['global']['mmol_to_counts']

        # kinetic rate law requires a flat dict with ('port', 'state') keys.
        flattened_states = tuplify_port_dicts(states)

        # get flux
        fluxes = self.kinetic_rate_laws.get_fluxes(flattened_states)

        # make the update
        # add fluxes to update
        update = {port: {} for port in self.port_ids}
        update.update({'fluxes': fluxes})

        # get exchange
        for reaction_id, flux in fluxes.items():
            stoichiometry = self.reactions[reaction_id]['stoichiometry']
            for port_state_id, coeff in stoichiometry.items():
                for port_id in self.port_ids:
                    # separate the state_id and port_id
                    if port_id in port_state_id:
                        state_id = port_state_id[1]
                        state_flux = coeff * flux * timestep

                        if port_id == 'external':
                            # convert exchange fluxes to counts with mmol_to_counts
                            # TODO -- use deriver to get exchanges
                            delta_counts = int((state_flux * mmol_to_counts).magnitude)
                            update['exchange'][state_id] = (
                                update['exchange'].get(state_id, 0)
                                + delta_counts
                            )
                        else:
                            update[port_id][state_id] = (
                                update[port_id].get(state_id, 0)
                                + state_flux
                            )

        # note: external and internal ports update change in mmol.
        return update
Exemple #3
0
    def next_update(self, timestep, states):
        internal = states['internal']
        step_size = self.parameters['step_size']
        n_steps = int(timestep / step_size)

        # get state of regulated reactions (True/False)
        flattened_states = tuplify_port_dicts(states)
        regulation_state = {}
        for gene_id, reg_logic in self.regulation.items():
            regulation_state[gene_id] = reg_logic(flattened_states)

        internal_update = {state_id: 0 for state_id in internal.keys()}
        for state_id in internal.keys():
            if state_id in regulation_state and not regulation_state[state_id]:
                break
            rate = self.parameters['expression_rates'][state_id]
            for step in range(n_steps):
                if random.random() < rate:
                    internal_update[state_id] += 1

        return {'internal': internal_update}
    def next_update(self, timestep, states):
        internal_state = states['internal']

        # get state of regulated reactions (True/False)
        flattened_states = tuplify_port_dicts(states)
        regulation_state = {}
        for gene_id, reg_logic in self.regulation.items():
            regulation_state[gene_id] = reg_logic(flattened_states)

        internal_update = {}
        # transcription: dM/dt = k_M - d_M * M
        # M: conc of mRNA, k_M: transcription rate, d_M: degradation rate
        for transcript, rate in self.transcription.items():
            transcript_state = internal_state[transcript]

            # do not transcribe inhibited genes, except for transcription leaks
            if transcript in regulation_state and regulation_state.get(
                    transcript):
                # leak probability for probability as function of the time step
                rate = -math.log(1 - self.transcription_leak_rate)
                leak_probability = 1 - math.exp(-rate * timestep)
                if random.uniform(0, 1) < leak_probability:
                    rate = self.transcription_leak_magnitude
                else:
                    rate = 0.0

            internal_update[transcript] = \
                (rate - self.degradation.get(transcript, 0) * transcript_state) * timestep

        # translation: dP/dt = k_P * m_P - d_P * P
        # P: conc of protein, m_P: conc of P's transcript, k_P: translation rate, d_P: degradation rate
        for protein, rate in self.translation.items():
            transcript = self.protein_map[protein]
            transcript_state = internal_state[transcript]
            protein_state = internal_state[protein]

            internal_update[protein] = \
                (rate * transcript_state - self.degradation.get(protein, 0) * protein_state) * timestep

        return {'internal': internal_update}
Exemple #5
0
    def next_update(self, timestep, states):
        internal_state = states['internal']

        # get state of regulated reactions (True/False)
        flattened_states = tuplify_port_dicts(states)
        regulation_state = {}
        for gene_id, reg_logic in self.regulation.items():
            regulation_state[gene_id] = reg_logic(flattened_states)

        internal_update = {}
        # transcription: dM/dt = k_M - d_M * M
        # M: conc of mRNA, k_M: transcription rate, d_M: degradation rate
        for transcript, rate in self.transcription.items():
            transcript_state = internal_state[transcript]
            # do not transcribe inhibited genes
            if transcript in regulation_state and not regulation_state[
                    transcript]:
                if random.uniform(0, 1) < abs(
                        random.gauss(0, self.transcription_leak_sigma)):
                    rate = self.transcription_leak_magnitude
                else:
                    rate = 0.0

            internal_update[transcript] = \
                (rate - self.degradation.get(transcript, 0) * transcript_state) * timestep

        # translation: dP/dt = k_P * m_P - d_P * P
        # P: conc of protein, m_P: conc of P's transcript, k_P: translation rate, d_P: degradation rate
        for protein, rate in self.translation.items():
            transcript = self.protein_map[protein]
            transcript_state = internal_state[transcript]
            protein_state = internal_state[protein]

            internal_update[protein] = \
                (rate * transcript_state - self.degradation.get(protein, 0) * protein_state) * timestep

        return {'internal': internal_update}
Exemple #6
0
def test_kinetics():
    kinetic_rate_laws = KineticFluxModel(toy_reactions, toy_kinetics)
    flattened_toy_states = tuplify_port_dicts(toy_initial_state)
    flux = kinetic_rate_laws.get_fluxes(flattened_toy_states)

    print(flux)
    def next_update(self, timestep, states):
        ## get the state
        external_state = states['external']
        constrained_reaction_bounds = states[
            'flux_bounds']  # (units.mmol / units.L / units.s)
        mmol_to_counts = states['global']['mmol_to_counts']

        ## get flux constraints
        # exchange_constraints based on external availability
        exchange_constraints = {
            mol_id: 0.0
            for mol_id, conc in external_state.items()
            if conc <= self.exchange_threshold
        }

        # get state of regulated reactions (True/False)
        flattened_states = tuplify_port_dicts(states)
        regulation_state = {}
        for reaction_id, reg_logic in self.regulation.items():
            regulation_state[reaction_id] = reg_logic(flattened_states)

        ## apply flux constraints
        # first, add exchange constraints
        self.fba.set_exchange_bounds(exchange_constraints)

        # next, add constraints coming from flux_bounds
        # to constrain exchange fluxes, add the suffix 'EX_' to the external molecule ID
        if constrained_reaction_bounds:
            self.fba.constrain_flux(constrained_reaction_bounds)

        # finally, turn reactions on/off based on regulation
        self.fba.regulate_flux(regulation_state)

        ## solve the fba problem
        objective_exchange = self.fba.optimize(
        ) * timestep  # (units.mmol / units.L / units.s)
        exchange_reactions = self.fba.read_exchange_reactions()
        exchange_fluxes = self.fba.read_exchange_fluxes(
        )  # (units.mmol / units.L / units.s)
        internal_fluxes = self.fba.read_internal_fluxes(
        )  # (units.mmol / units.L / units.s)

        # timestep dependence on fluxes
        exchange_fluxes.update((mol_id, flux * timestep)
                               for mol_id, flux in exchange_fluxes.items())
        internal_fluxes.update((mol_id, flux * timestep)
                               for mol_id, flux in internal_fluxes.items())

        # update internal counts from objective flux
        # calculate added mass from the objective molecules' molecular weights
        objective_count = (objective_exchange * mmol_to_counts).magnitude
        internal_state_update = {}
        for reaction_id, coeff1 in self.fba.objective.items():
            for mol_id, coeff2 in self.fba.stoichiometry[reaction_id].items():
                if coeff2 < 0:  # pull out molecule if it is USED to make biomass (negative coefficient)
                    added_count = int(-coeff1 * coeff2 * objective_count)
                    internal_state_update[mol_id] = added_count

        # convert exchange fluxes to counts
        field_updates = {
            reaction: {
                '_value': int((flux * mmol_to_counts).magnitude),
                '_updater': {
                    'updater': 'update_field_with_exchange',
                    'port_mapping': {
                        'global': 'global',
                        'dimensions': 'dimensions',
                    },
                },
            }
            for reaction, flux in exchange_fluxes.items()
        }

        all_fluxes = {}
        all_fluxes.update(internal_fluxes)
        all_fluxes.update(exchange_reactions)

        return {
            'fields': field_updates,
            'internal': internal_state_update,
            'reactions': all_fluxes,
        }
Exemple #8
0
    def next_update(self, timestep, states):

        # get the state
        external_state = states['external']
        flux_bounds = states['flux_bounds']  # mmol/L/s
        mmol_to_counts = states['global']['mmol_to_counts'].to(
            'L/mmol').magnitude

        # get constraints
        ## exchange_constraints based on external availability
        exchange_constraints = {
            mol_id: 0.0
            for mol_id, conc in external_state.items()
            if conc <= self.parameters['exchange_threshold']
        }

        ## state of regulated reactions (True/False)
        flattened_states = tuplify_port_dicts(states)
        regulation_state = {}
        for reaction_id, reg_logic in self.regulation.items():
            regulation_state[reaction_id] = reg_logic(flattened_states)

        # apply constraints
        ## exchange constraints
        self.fba.set_exchange_bounds(exchange_constraints)

        ## constraints from flux_bounds
        if flux_bounds:
            # only pass in reaction_ids that exist in the fba model
            constrained_reaction_bounds = {
                reaction_id: constraint
                for reaction_id, constraint in flux_bounds.items()
                if reaction_id in self.reaction_ids
            }
            self.fba.constrain_flux(constrained_reaction_bounds)

        ## turn reactions on/off based on regulation
        self.fba.regulate_flux(regulation_state)

        # solve the fba problem
        objective_exchange = self.fba.optimize() * timestep  # mmol/L/s
        exchange_reactions = self.fba.read_exchange_reactions()
        exchange_fluxes = self.fba.read_exchange_fluxes()  # mmol/L/s
        internal_fluxes = self.fba.read_internal_fluxes()  # mmol/L/s

        # convert results
        ## time step dependence on fluxes
        exchange_fluxes.update((mol_id, flux * timestep)
                               for mol_id, flux in exchange_fluxes.items())
        internal_fluxes.update((mol_id, flux * timestep)
                               for mol_id, flux in internal_fluxes.items())

        ## update internal counts from objective flux
        ## calculate added mass from the objective molecules' molecular weights
        objective_count = objective_exchange * mmol_to_counts

        if self.parameters[
                'no_negative_objective'] and objective_exchange < 0.0:
            return {}

        internal_state_update = {}
        for reaction_id, coeff1 in self.fba.objective.items():
            for mol_id, coeff2 in self.fba.stoichiometry[reaction_id].items():
                if coeff2 < 0:  # pull out molecule if it is used to make biomass (negative coefficient)
                    added_count = int(-coeff1 * coeff2 * objective_count)
                    internal_state_update[mol_id] = added_count

        ## convert exchange fluxes to counts
        exchanges_updates = {
            mol_id: int(flux * mmol_to_counts)
            for mol_id, flux in exchange_fluxes.items()
        }

        all_fluxes = {}
        all_fluxes.update(internal_fluxes)
        all_fluxes.update(exchange_reactions)

        update = {
            'exchanges': exchanges_updates,
            'internal_counts': internal_state_update,
            'reactions': all_fluxes
        }

        return update