Beispiel #1
0
def process_gene_knockout_solution(model, solution, simulation_method,
                                   simulation_kwargs, biomass, target,
                                   substrate, objective_function):
    """

    Arguments
    ---------

    model: SolverBasedModel
        A constraint-based model
    solution: tuple
        The genes
    simulation_method: function
        See see cameo.flux_analysis.simulation
    simulation_kwargs: dict
        Keyword arguments to run the simulation method
    biomass: Reaction
        Cellular biomass reaction
    target: Reaction
        The strain design target
    substrate: Reaction
        The main carbon source uptake rate
    objective_function: cameo.strain_design.heuristic.evolutionary.objective_functions.ObjectiveFunction
        The objective function used for evaluation.

    Returns
    -------

    list
        A list with: reactions, genes, size, fva_min, fva_max, target flux, biomass flux, yield, fitness
    """

    with TimeMachine() as tm:
        genes = [model.genes.get_by_id(gid) for gid in solution]
        reactions = find_gene_knockout_reactions(model, solution)
        for reaction in reactions:
            reaction.knock_out(tm)

        reaction_ids = [r.id for r in reactions]
        flux_dist = simulation_method(model,
                                      reactions=objective_function.reactions,
                                      objective=biomass,
                                      **simulation_kwargs)
        tm(do=partial(setattr, model, "objective", biomass),
           undo=partial(setattr, model, "objective", model.objective))

        fva = flux_variability_analysis(model,
                                        fraction_of_optimum=0.99,
                                        reactions=[target])
        target_yield = flux_dist[target] / abs(flux_dist[substrate])

        return [
            tuple(reaction_ids), solution,
            len(solution),
            fva.lower_bound(target),
            fva.upper_bound(target), flux_dist[target], flux_dist[biomass],
            target_yield,
            objective_function(model, flux_dist, genes)
        ]
Beispiel #2
0
def _gene_deletion(model, ids):
    all_reactions = []
    for g_id in ids:
        all_reactions.extend(
            find_gene_knockout_reactions(model,
                                         (model.genes.get_by_id(g_id), )))
    _, growth, status = _reactions_knockouts_with_restore(model, all_reactions)
    return (ids, growth, status)
Beispiel #3
0
    def visualize(self, index, map_name):
        if type == REACTION_KNOCKOUT_TYPE:
            knockouts = self.solutions[KNOCKOUTS][index]
        else:
            genes = [self.model.genes.get_by_id(g) for g in self.solutions[KNOCKOUTS][index]]
            knockouts = find_gene_knockout_reactions(self.model, genes)

        builder = draw_knockout_result(self.model, map_name, self.simulation_method, knockouts)
        return builder.display_in_notebook()
Beispiel #4
0
def _gene_deletion(model, ids):
    all_reactions = []
    for g_id in ids:
        all_reactions.extend(
            find_gene_knockout_reactions(
                model, (model.genes.get_by_id(g_id),)
            )
        )
    _, growth, status = _reactions_knockouts_with_restore(model, all_reactions)
    return (ids, growth, status)
 def run(gene_ids):
     ko_reactions = find_gene_knockout_reactions(cobra_model, gene_ids)
     ko_indexes = map(cobra_model.reactions.index, ko_reactions)
     # If all the reactions carry no flux, deletion will have no effect.
     if no_flux_reaction_indexes.issuperset(gene_ids):
         return wt_growth_rate
     return moma.moma_knockout(moma_model,
                               moma_obj,
                               ko_indexes,
                               solver=solver,
                               **kwargs).f
Beispiel #6
0
    def simulate_knockout(self, to_knockout, *args, **kwargs):
        reactions = find_gene_knockout_reactions(self._model, [to_knockout])
        cache = {"variables": {}, "constraints": {}, "first_run": True}

        with self._model:
            for reaction in reactions:
                reaction.knock_out()

            return self._simulation_method(
                self._model, volatile=False, cache=cache, *args,
                **kwargs)[cache['original_objective']]
Beispiel #7
0
    def visualize(self, index, map_name):
        if type == REACTION_KNOCKOUT_TYPE:
            knockouts = self.solutions[KNOCKOUTS][index]
        else:
            genes = [
                self.model.genes.get_by_id(g)
                for g in self.solutions[KNOCKOUTS][index]
            ]
            knockouts = find_gene_knockout_reactions(self.model, genes)

        builder = draw_knockout_result(self.model, map_name,
                                       self.simulation_method, knockouts)
        return builder.display_in_notebook()
Beispiel #8
0
def process_gene_knockout_solution(model, solution, simulation_method, simulation_kwargs,
                                   biomass, target, substrate, objective_function):
    """

    Arguments
    ---------

    model: cobra.Model
        A constraint-based model
    solution: tuple
        The genes
    simulation_method: function
        See see cameo.flux_analysis.simulation
    simulation_kwargs: dict
        Keyword arguments to run the simulation method
    biomass: Reaction
        Cellular biomass reaction
    target: Reaction
        The strain design target
    substrate: Reaction
        The main carbon source uptake rate
    objective_function: cameo.strain_design.heuristic.evolutionary.objective_functions.ObjectiveFunction
        The objective function used for evaluation.

    Returns
    -------

    list
        A list with: reactions, genes, size, fva_min, fva_max, target flux, biomass flux, yield, fitness
    """

    with model:
        genes = [model.genes.get_by_id(gid) for gid in solution]
        reactions = find_gene_knockout_reactions(model, solution)
        for reaction in reactions:
            reaction.knock_out()

        reaction_ids = [r.id for r in reactions]
        flux_dist = simulation_method(model, reactions=objective_function.reactions,
                                      objective=biomass, **simulation_kwargs)
        model.objective = biomass

        fva = flux_variability_analysis(model, fraction_of_optimum=0.99, reactions=[target])
        target_yield = flux_dist[target] / abs(flux_dist[substrate])

        return [tuple(reaction_ids), solution, len(solution), fva.lower_bound(target), fva.upper_bound(target),
                flux_dist[target], flux_dist[biomass], target_yield, objective_function(model, flux_dist, genes)]
Beispiel #9
0
    def simulate_knockout(self, to_knockout, *args, **kwargs):
        reactions = find_gene_knockout_reactions(self._model, [to_knockout])
        cache = {
            "variables": {},
            "constraints": {},
            "first_run": True
        }

        with TimeMachine() as tm:
            for reaction in reactions:
                reaction.knock_out(tm)

            return self._simulation_method(self._model,
                                           volatile=False,
                                           cache=cache,
                                           *args,
                                           **kwargs)[cache['original_objective']]
Beispiel #10
0
    def __call__(self, individual):
        """
        Parameters
        ----------

        individual : list
            a list of integers

        Returns
        -------
        list
            [knockouts, decoded representation]

        """
        genes = [self.model.genes.get_by_id(self.representation[index]) for index in individual]
        reactions = find_gene_knockout_reactions(self.model, genes)
        return [reactions, genes]
Beispiel #11
0
def gene_knockout_growth(
    gene_id,
    model,
    threshold=10 ** -6,
    simulation_method=fba,
    normalize=True,
    biomass=None,
    biomass_flux=None,
    *args,
    **kwargs
):
    if biomass_flux is None:
        s = model.solve()
        biomass_flux = s.f
    if "reference" not in kwargs:
        kwargs["reference"] = s.x_dict
    gene = model.genes.get_by_id(gene_id)
    knockouts = find_gene_knockout_reactions(model, [gene])
    tm = TimeMachine()

    for reaction in knockouts:
        tm(
            do=partial(setattr, reaction, "lower_bound", 0),
            undo=partial(setattr, reaction, "lower_bound", reaction.lower_bound),
        )
        tm(
            do=partial(setattr, reaction, "upper_bound", 0),
            undo=partial(setattr, reaction, "upper_bound", reaction.upper_bound),
        )

    try:
        s = simulation_method(model, *args, **kwargs)
        f = s.get_primal_by_id(biomass)
        if f >= threshold:
            if normalize:
                f = f / biomass_flux
        else:
            f = 0
    except SolveError:
        f = float("nan")
    finally:
        tm.reset()

    return f
Beispiel #12
0
    def __call__(self, individual):
        """
        Parameters
        ----------

        individual : list
            a list of integers

        Returns
        -------
        list
            [knockouts, decoded representation]

        """
        genes = [
            self.model.genes.get_by_id(self.representation[index])
            for index in individual
        ]
        reactions = find_gene_knockout_reactions(self.model, genes)
        return [reactions, genes]
Beispiel #13
0
def gene_knockout_growth(gene_id,
                         model,
                         threshold=10**-6,
                         simulation_method=fba,
                         normalize=True,
                         biomass=None,
                         biomass_flux=None,
                         *args,
                         **kwargs):
    if biomass_flux is None:
        s = model.solve()
        biomass_flux = s.f
    if 'reference' not in kwargs:
        kwargs['reference'] = s.x_dict
    gene = model.genes.get_by_id(gene_id)
    knockouts = find_gene_knockout_reactions(model, [gene])
    tm = TimeMachine()

    for reaction in knockouts:
        tm(do=partial(setattr, reaction, 'lower_bound', 0),
           undo=partial(setattr, reaction, 'lower_bound',
                        reaction.lower_bound))
        tm(do=partial(setattr, reaction, 'upper_bound', 0),
           undo=partial(setattr, reaction, 'upper_bound',
                        reaction.upper_bound))

    try:
        s = simulation_method(model, *args, **kwargs)
        f = s.get_primal_by_id(biomass)
        if f >= threshold:
            if normalize:
                f = f / biomass_flux
        else:
            f = 0
    except SolveError:
        f = float('nan')
    finally:
        tm.reset()

    return f
Beispiel #14
0
    def __call__(self, individual, flat=False):
        """
        Parameters
        ----------

        individual: list
            a list of integers
        flat: bool
            if True, returns strings. Otherwise returns Gene

        Returns
        -------
        list
            [knockouts, decoded representation]

        """
        genes = [self.model.genes.get_by_id(self.representation[index]) for index in individual]
        reactions = find_gene_knockout_reactions(self.model, genes)

        if flat:
            return [tuple(r.id for r in reactions), tuple(g.id for g in genes)]
        return [tuple(reactions), tuple(genes)]
    def find_essential_genes_reactions(self):
        """ If the model has genes finds the reactions associated with the essential genes.
			Searches essential genes if hasn't done before.

		"""
        errors = []
        try:
            if self.__essential_genes is not None:
                # Dict with reaction as key and list of genes as value
                reactions = {}
                for gene in self.__essential_genes:
                    reactions_knock = find_gene_knockout_reactions(
                        self.__cobra_model, [gene])
                    for reaction in reactions_knock:
                        if reaction in reactions:
                            reactions[reaction].append(gene)
                        else:
                            reactions[reaction] = [gene]
                self.__essential_genes_reactions = reactions
        except Exception as error:
            self.__essential_genes_reactions = {}
            errors.append(str(error))
        return errors
Beispiel #16
0
    def knock_out(self, time_machine=None):
        """Knockout gene by setting all its affected reactions' bounds to zero.

        Parameters
        ----------
        time_machine = TimeMachine
            A time TimeMachine instance can be provided to undo the knockout eventually.

        Returns
        -------
        None
        """

        from cobra.manipulation.delete import find_gene_knockout_reactions
        for reaction in find_gene_knockout_reactions(self.model, [self]):
            def _(reaction, lb, ub):
                reaction.upper_bound = ub
                reaction.lower_bound = lb

            if time_machine is not None:
                time_machine(do=reaction.knock_out, undo=partial(_, reaction, reaction.lower_bound, reaction.upper_bound))
            else:
                reaction.knock_out()
def _double_gene_deletion_fba(cobra_model,
                              gene_ids1,
                              gene_ids2,
                              gene_id_to_result,
                              solver,
                              number_of_processes=None,
                              zero_cutoff=1e-12,
                              wt_growth_rate=None,
                              no_flux_reaction_indexes=set(),
                              **kwargs):
    """compute double gene deletions using fba

    cobra_model: model

    gene_ids1, gene_ids2: lists of id's to be knocked out

    gene_id_to_result: maps each gene identifier to the entry in
        the result matrix

    no_flux_reaction_indexes: set of indexes for reactions in the model
        which carry no flux in an optimal solution. For deletions only in
        this set, the result will beset to wt_growth_rate.

    returns an upper triangular square matrix
    """
    # Because each gene reaction rule will be evaluated multiple times
    # the reaction has multiple associated genes being deleted, compiling
    # the gene reaction rules ahead of time increases efficiency greatly.
    compiled_rules = get_compiled_gene_reaction_rules(cobra_model)

    n_results = len(gene_id_to_result)
    results = numpy.empty((n_results, n_results))
    results.fill(numpy.nan)

    if number_of_processes == 1:  # explicitly disable multiprocessing
        PoolClass = CobraDeletionMockPool
    else:
        PoolClass = CobraDeletionPool
    with PoolClass(cobra_model,
                   n_processes=number_of_processes,
                   solver=solver,
                   **kwargs) as pool:
        # precompute all single deletions in the pool and store them along
        # the diagonal
        for gene_id, gene_result_index in iteritems(gene_id_to_result):
            ko_reactions = find_gene_knockout_reactions(
                cobra_model, (cobra_model.genes.get_by_id(gene_id), ))
            ko_indexes = [cobra_model.reactions.index(i) for i in ko_reactions]
            pool.submit(ko_indexes, label=gene_result_index)
        for result_index, value in pool.receive_all():
            # if singly lethal, set everything in row and column to 0
            value = value if abs(value) > zero_cutoff else 0.
            if value == 0.:
                results[result_index, :] = 0.
                results[:, result_index] = 0.
            else:  # only the diagonal needs to be set
                results[result_index, result_index] = value

        # Run double knockouts in the upper triangle
        index_selector = yield_upper_tria_indexes(gene_ids1, gene_ids2,
                                                  gene_id_to_result)
        for result_index, (gene1, gene2) in index_selector:

            # if singly lethal the results have already been set
            if results[result_index] == 0:
                continue
            ko_reactions = find_gene_knockout_reactions(
                cobra_model, (gene1, gene2), compiled_rules)
            ko_indexes = [cobra_model.reactions.index(i) for i in ko_reactions]
            # if all removed gene indexes carry no flux
            if len(set(ko_indexes) - no_flux_reaction_indexes) == 0:
                results[result_index] = wt_growth_rate
                continue
            pool.submit(ko_indexes, label=result_index)

        for result in pool.receive_all():
            value = result[1]
            if value < zero_cutoff:
                value = 0
            results[result[0]] = value

    return results
Beispiel #18
0
def single_gene_deletion_fba(cobra_model, gene_list, solver=None,
                             **solver_args):
    """Sequentially knocks out each gene in a model using FBA.

    Not supposed to be called directly use
    `single_reactions_deletion(..., method="fba")` instead.

    Parameters
    ----------
    gene_list : iterable
        List of gene IDs or cobra.Reaction.
    solver: str, optional
        The name of the solver to be used.

    Returns
    -------
    tuple of dicts
        A tuple ({reaction_id: growth_rate}, {reaction_id: status})
    """
    legacy = False
    if solver is None:
        solver = cobra_model.solver
    elif "optlang-" in solver:
        solver = solvers.interface_to_str(solver)
        solver = solvers.solvers[solver]
    else:
        legacy = True
        solver = legacy_solvers.solver_dict[solver]
        lp = solver.create_problem(cobra_model)

    growth_rate_dict = {}
    status_dict = {}

    if not legacy:
        with cobra_model as m:
            m.solver = solver
            for gene in gene_list:
                ko = find_gene_knockout_reactions(cobra_model, [gene])
                with m:
                    for reaction in ko:
                        reaction.bounds = (0.0, 0.0)
                    m.solver.optimize()
                    status = m.solver.status
                    status_dict[gene.id] = status
                    growth_rate_dict[gene.id] = m.solver.objective.value if \
                        status == OPTIMAL else 0.
    else:
        for gene in gene_list:
            old_bounds = {}
            for reaction in find_gene_knockout_reactions(cobra_model, [gene]):
                index = cobra_model.reactions.index(reaction)
                old_bounds[index] = reaction.bounds
                solver.change_variable_bounds(lp, index, 0., 0.)
            solver.solve_problem(lp, **solver_args)
            # get the status and growth rate
            status = solver.get_status(lp)
            status_dict[gene.id] = status
            growth_rate = solver.get_objective_value(lp) \
                if status == "optimal" else 0.
            growth_rate_dict[gene.id] = growth_rate
            # reset the problem
            for index, bounds in iteritems(old_bounds):
                solver.change_variable_bounds(lp, index, bounds[0], bounds[1])
    return growth_rate_dict, status_dict
Beispiel #19
0
def single_gene_deletion_moma(cobra_model, gene_list, solver=None,
                              **solver_args):
    """Sequentially knocks out each gene in a model using MOMA.

    Not supposed to be called directly use
    `single_reactions_deletion(..., method="moma")` instead.

    Parameters
    ----------
    gene_list : iterable
        List of gene IDs or cobra.Reaction.
    solver: str, optional
        The name of the solver to be used.

    Returns
    -------
    tuple of dicts
        A tuple ({reaction_id: growth_rate}, {reaction_id: status})
    """
    if moma is None:
        raise RuntimeError("scipy required for moma")

    legacy = False
    if solver is None:
        solver = cobra_model.solver
    elif "optlang-" in solver:
        solver = solvers.interface_to_str(solver)
        solver = solvers.solvers[solver]
    else:
        legacy = True
        solver = legacy_solvers.solver_dict[solver]
        moma_model, moma_objective = moma.create_euclidian_moma_model(
            cobra_model)

    growth_rate_dict = {}
    status_dict = {}

    if not legacy:
        with cobra_model as m:
            m.solver = solver
            moma.add_moma(m)
            for gene in gene_list:
                ko = find_gene_knockout_reactions(cobra_model, [gene])
                with m:
                    for reaction in ko:
                        reaction.bounds = (0.0, 0.0)
                    m.solver.optimize()
                    status = m.solver.status
                    status_dict[gene.id] = status
                    if status == "optimal":
                        growth = m.variables.moma_old_objective.primal
                    else:
                        growth = 0.0
                    growth_rate_dict[gene.id] = growth
    else:
        for gene in gene_list:
            delete_model_genes(moma_model, [gene.id])
            solution = moma.solve_moma_model(moma_model, moma_objective,
                                             solver=solver, **solver_args)
            status_dict[gene.id] = solution.status
            growth_rate_dict[gene.id] = solution.f
            undelete_model_genes(moma_model)
    return growth_rate_dict, status_dict
 def test_gene_knockout_decoder(self):
     decoder = GeneKnockoutDecoder([g.id for g in self.model.genes], self.model)
     reactions1, genes = decoder([1, 2, 3, 4])
     reactions2 = find_gene_knockout_reactions(self.model, genes)
     self.assertTrue(sorted(reactions1, key=lambda x: x.id) == sorted(reactions2, key=lambda x: x.id))
Beispiel #21
0
 def test_gene_knockout_decoder(self):
     decoder = GeneKnockoutDecoder([g.id for g in self.model.genes], self.model)
     reactions1, genes = decoder([1, 2, 3, 4])
     reactions2 = find_gene_knockout_reactions(self.model, genes)
     self.assertTrue(sorted(reactions1, key=lambda x: x.id) == sorted(reactions2, key=lambda x: x.id))