Пример #1
0
def _fbid_fva(model, knockouts, view):
    tm = TimeMachine()
    for reaction in model.reactions:
        if reaction.reversibility:
            tm(do=partial(setattr, reaction, 'lower_bound', -1),
               undo=partial(setattr, reaction, 'lower_bound', reaction.lower_bound))
            tm(do=partial(setattr, reaction, 'upper_bound', 1),
               undo=partial(setattr, reaction, 'upper_bound', reaction.upper_bound))
        else:
            tm(do=partial(setattr, reaction, 'lower_bound', 0),
               undo=partial(setattr, reaction, 'lower_bound', reaction.lower_bound))
            tm(do=partial(setattr, reaction, 'upper_bound', 1),
               undo=partial(setattr, reaction, 'upper_bound', reaction.upper_bound))

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

    mt_fva = flux_variability_analysis(model, view)

    perturbation = 0
    for reaction in model.reactions:
        if wt_fva[reaction.id] != 0 and mt_fva[reaction.id] == 0:
            perturbation += 1

    tm.reset()
    return perturbation
Пример #2
0
 def _production_envelope_inner(self, point):
     tm = TimeMachine()
     try:
         for (reaction, coordinate) in zip(self.variable_reactions, point):
             tm(do=partial(setattr, reaction, 'lower_bound', coordinate),
                undo=partial(setattr, reaction, 'lower_bound',
                             reaction.lower_bound))
             tm(do=partial(setattr, reaction, 'upper_bound', coordinate),
                undo=partial(setattr, reaction, 'upper_bound',
                             reaction.upper_bound))
         interval = []
         tm(do=int,
            undo=partial(setattr, self.model.objective, 'direction',
                         self.model.objective.direction))
         self.model.objective.direction = 'min'
         try:
             solution = self.model.solve().f
         except Infeasible:
             solution = 0
         interval.append(solution)
         self.model.objective.direction = 'max'
         try:
             solution = self.model.solve().f
         except Infeasible:
             solution = 0
         interval.append(solution)
     finally:
         tm.reset()
     return point + tuple(interval)
Пример #3
0
    def test_reaction_cofactor_swap_target(self, model):
        cofactor_id_swaps = [("nad_c", "nadh_c"), ("nadp_c", "nadph_c")]

        swap_pairs = ([
            model.metabolites.get_by_id(m) for m in cofactor_id_swaps[0]
        ], [model.metabolites.get_by_id(m) for m in cofactor_id_swaps[1]])

        swap_target = ReactionCofactorSwapTarget("GAPD", swap_pairs)
        with TimeMachine() as tm:
            swap_target.apply(model, time_machine=tm)
            assert model.metabolites.nad_c not in model.reactions.GAPD.metabolites
            assert model.metabolites.nadh_c not in model.reactions.GAPD.metabolites
            assert model.metabolites.nadp_c in model.reactions.GAPD.metabolites
            assert model.metabolites.nadph_c in model.reactions.GAPD.metabolites

        assert model.metabolites.nadp_c not in model.reactions.GAPD.metabolites
        assert model.metabolites.nadph_c not in model.reactions.GAPD.metabolites
        assert model.metabolites.nad_c in model.reactions.GAPD.metabolites
        assert model.metabolites.nadh_c in model.reactions.GAPD.metabolites

        swap_target = ReactionCofactorSwapTarget("GND", swap_pairs)
        with TimeMachine() as tm:
            swap_target.apply(model, time_machine=tm)
            assert model.metabolites.nad_c in model.reactions.GND.metabolites
            assert model.metabolites.nadh_c in model.reactions.GND.metabolites
            assert model.metabolites.nadp_c not in model.reactions.GND.metabolites
            assert model.metabolites.nadph_c not in model.reactions.GND.metabolites

        assert model.metabolites.nadp_c in model.reactions.GND.metabolites
        assert model.metabolites.nadph_c in model.reactions.GND.metabolites
        assert model.metabolites.nad_c not in model.reactions.GND.metabolites
        assert model.metabolites.nadh_c not in model.reactions.GND.metabolites
Пример #4
0
 def test_one_change_list(self):
     tm = TimeMachine()
     l = [1, 2, 3, 4]
     tm(do=partial(l.append, 5), undo=l.pop)
     assert l == [1, 2, 3, 4, 5]
     tm.reset()
     assert l == [1, 2, 3, 4]
Пример #5
0
    def test_reaction_down_regulation_target(self, model):
        reaction_id = "PGI"
        ref_val = 4.86
        value = 3.4

        # (B - A) / A
        fold_change = -0.30041

        down_reg_target = ReactionModulationTarget(reaction_id, value, ref_val)
        assert round(abs(down_reg_target.fold_change - fold_change), 5) == 0
        with TimeMachine() as tm:
            down_reg_target.apply(model, time_machine=tm)
            assert model.reactions.PGI.upper_bound == 3.4
            assert model.reactions.PGI.lower_bound == -1000
            assert abs(model.solve().f - 0.8706) < 0.0001

        assert model.reactions.PGI.upper_bound == 1000
        assert model.reactions.PGI.lower_bound == -1000

        reaction_id = "RPI"
        ref_val = -2.28150
        value = -1.5

        fold_change = -0.342537

        down_reg_target = ReactionModulationTarget(reaction_id, value, ref_val)
        assert round(abs(down_reg_target.fold_change - fold_change), 5) == 0
        with TimeMachine() as tm:
            down_reg_target.apply(model, time_machine=tm)
            assert model.reactions.RPI.lower_bound == -1.5
            assert model.reactions.RPI.upper_bound == 1000
            assert abs(model.solve().f - 0.8691) < 0.0001

        assert model.reactions.RPI.lower_bound == -1000
        assert model.reactions.RPI.upper_bound == 1000
Пример #6
0
class TimeMachineTestCase(unittest.TestCase):
    def setUp(self):
        self.tm = TimeMachine()

    def test_one_change_list(self):
        l = [1, 2, 3, 4]
        self.tm(do=partial(l.append, 5), undo=l.pop)
        self.assertEqual(l, [1, 2, 3, 4, 5])
        self.tm.reset()
        self.assertEqual(l, [1, 2, 3, 4])

    def test_str_handles_different_types_of_stored_operations(self):
        def normal_function():
            pass

        partial_function = partial(str, 1)
        self.tm(do=normal_function, undo=partial_function)
        self.assertEqual(self.tm.__str__().split('\n')[2:-1],
                         ["undo: " + str(str) + " (1,) {}", 'redo: normal_function'])

    def test_with_statement(self):
        l = [1, 2, 3, 4]
        with TimeMachine() as tm:
            tm(do=partial(l.append, 33), undo=partial(l.pop))
            tm(do=partial(l.append, 66), undo=partial(l.pop))
            tm(do=partial(l.append, 99), undo=partial(l.pop))
        self.assertEqual(l, [1, 2, 3, 4])
Пример #7
0
 def _production_envelope_inner(self, point):
     tm = TimeMachine()
     try:
         for (reaction, coordinate) in zip(self.variable_reactions, point):
             tm(do=partial(setattr, reaction, 'lower_bound', coordinate),
                undo=partial(setattr, reaction, 'lower_bound', reaction.lower_bound))
             tm(do=partial(setattr, reaction, 'upper_bound', coordinate),
                undo=partial(setattr, reaction, 'upper_bound', reaction.upper_bound))
         interval = []
         tm(do=int, undo=partial(setattr, self.model.objective, 'direction', self.model.objective.direction))
         self.model.objective.direction = 'min'
         try:
             solution = self.model.solve().f
         except Infeasible:
             solution = 0
         interval.append(solution)
         self.model.objective.direction = 'max'
         try:
             solution = self.model.solve().f
         except Infeasible:
             solution = 0
         interval.append(solution)
     finally:
         tm.reset()
     return point + tuple(interval)
Пример #8
0
class TimeMachineTestCase(unittest.TestCase):
    def setUp(self):
        self.tm = TimeMachine()

    def test_one_change_list(self):
        l = [1, 2, 3, 4]
        self.tm(do=partial(l.append, 5), undo=l.pop)
        self.assertEqual(l, [1, 2, 3, 4, 5])
        self.tm.reset()
        self.assertEqual(l, [1, 2, 3, 4])

    def test_str_handles_different_types_of_stored_operations(self):
        def normal_function():
            pass

        partial_function = partial(str, 1)
        self.tm(do=normal_function, undo=partial_function)
        if six.PY2:
            self.assertEqual(
                self.tm.__str__().split('\n')[2:-1],
                ["undo: <type 'str'> (1,) None", 'redo: normal_function'])
        elif six.PY3:
            self.assertEqual(
                self.tm.__str__().split('\n')[2:-1],
                ["undo: <class 'str'> (1,) None", 'redo: normal_function'])

    def test_with_statement(self):
        l = [1, 2, 3, 4]
        with TimeMachine() as tm:
            tm(do=partial(l.append, 33), undo=partial(l.pop))
            tm(do=partial(l.append, 66), undo=partial(l.pop))
            tm(do=partial(l.append, 99), undo=partial(l.pop))
        self.assertEqual(l, [1, 2, 3, 4])
Пример #9
0
    def test_str_handles_different_types_of_stored_operations(self):
        tm = TimeMachine()

        def normal_function():
            pass

        partial_function = partial(str, 1)
        tm(do=normal_function, undo=partial_function)
        assert tm.__str__().split('\n')[2:-1] == ["undo: " + str(str) + " (1,) {}", 'redo: normal_function']
Пример #10
0
 def test_add_remove_pfb(self, core_model):
     with TimeMachine() as tm:
         add_pfba(core_model, time_machine=tm)
         assert '_pfba_objective' == core_model.objective.name
     assert '_pfba_objective' != core_model.solver.constraints
     with TimeMachine() as tm:
         fix_pfba_as_constraint(core_model, time_machine=tm)
         assert '_fixed_pfba_constraint' in core_model.solver.constraints
     assert '_fixed_pfba_constraint' not in core_model.solver.constraints
Пример #11
0
    def test_moma_shlomi_2005_change_ref(self, toy_model):
        if current_solver_name(toy_model) == 'glpk':
            pytest.skip('glpk does not support qp')

        original_objective = toy_model.objective
        reference = {
            "b1": 10,
            "v1": 10,
            "v2": 5,
            "v3": 0,
            "v4": 0,
            "v5": 0,
            "v6": 5,
            "b2": 5,
            "b3": 5
        }
        expected = {
            'b1': 8.8,
            'b2': 4.4,
            'b3': 4.4,
            'v1': 8.8,
            'v2': 3.1,
            'v3': 1.3,
            'v4': 4.4,
            'v5': 3.1,
            'v6': 0.0
        }

        with TimeMachine() as tm:
            toy_model.reactions.v6.knock_out(tm)
            result = moma(toy_model, reference=reference)

        for k in reference.keys():
            assert abs(expected[k] - result.fluxes[k]) < 0.1, "%s: %f | %f"
        assert toy_model.objective is original_objective

        reference_changed = {
            "b1": 5,
            "v1": 5,
            "v2": 5,
            "v3": 0,
            "v4": 0,
            "v5": 0,
            "v6": 5,
            "b2": 5,
            "b3": 5
        }
        with TimeMachine() as tm:
            toy_model.reactions.v6.knock_out(tm)
            result_changed = moma(toy_model, reference=reference_changed)

        assert expected != result_changed.fluxes
Пример #12
0
    def test_reactions_in_group_become_blocked_if_one_is_removed(
            self, core_model):
        essential_reactions = core_model.essential_reactions()
        coupled_reactions = structural.find_coupled_reactions_nullspace(
            core_model)
        for group in coupled_reactions:
            representative = pick_one(group)
            if representative not in essential_reactions:
                with TimeMachine() as tm:
                    assert core_model == representative.model
                    tm(do=partial(core_model.remove_reactions,
                                  [representative],
                                  delete=False),
                       undo=partial(core_model.add_reactions,
                                    [representative]))
                    # # FIXME: Hack because of optlang queue issues with GLPK
                    # core_model.solver.update()
                    assert representative not in core_model.reactions
                    assert representative.forward_variable not in core_model.solver.variables
                    assert representative.reverse_variable not in core_model.solver.variables
                    assert representative not in core_model.reactions
                    assert representative.model is None
                    blocked_reactions = find_blocked_reactions(core_model)
                    assert all(r in blocked_reactions for r in group
                               if r != representative)
                assert representative in core_model.reactions

        coupled_reactions = structural.find_coupled_reactions(core_model)
        for group in coupled_reactions:
            representative = pick_one(group)
            if representative not in essential_reactions:
                with TimeMachine() as tm:
                    fwd_var_name = representative.forward_variable.name
                    rev_var_name = representative.reverse_variable.name
                    assert core_model == representative.model
                    tm(do=partial(core_model.remove_reactions,
                                  [representative],
                                  delete=False),
                       undo=partial(core_model.add_reactions,
                                    [representative]))
                    # # FIXME: Hack because of optlang queue issues with GLPK
                    # core_model.solver.update()
                    assert representative not in core_model.reactions
                    assert fwd_var_name not in core_model.solver.variables
                    assert rev_var_name not in core_model.solver.variables
                    assert representative not in core_model.reactions
                    assert representative.model is None
                    blocked_reactions = find_blocked_reactions(core_model)
                    assert representative not in core_model.reactions
                    assert all(r in blocked_reactions for r in group
                               if r != representative)
                assert representative in core_model.reactions
Пример #13
0
def reaction_component_production(model, reaction):
    tm = TimeMachine()
    for metabolite in reaction.metabolites:
        test = Reaction("EX_%s_temp" % metabolite.id)
        test._metabolites[metabolite] = -1
        # hack frozen set from cobrapy to be able to add a reaction
        metabolite._reaction = set(metabolite._reaction)
        tm(do=partial(model.add_reactions, [test]), undo=partial(model.remove_reactions, [test]))
        tm(do=partial(setattr, model, "objective", test.id), undo=partial(setattr, model, "objective", model.objective))
        try:
            print(metabolite.id, "= ", model.solve().f)
        except SolveError:
            print(metabolite, " cannot be produced (reactions: %s)" % metabolite.reactions)
        finally:
            tm.reset()
Пример #14
0
    def _process_knockouts(self):
        progress = ProgressBar(
            maxval=len(self._knockouts),
            widgets=["Processing solutions: ",
                     Bar(), Percentage()])

        self._processed_knockouts = DataFrame(columns=[
            "reactions", "size", self._target, "biomass", "fva_min", "fva_max"
        ])

        for i, knockouts in progress(enumerate(self._knockouts)):
            try:
                with TimeMachine() as tm:
                    [
                        self._model.reactions.get_by_id(ko).knock_out(
                            time_machine=tm) for ko in knockouts
                    ]
                    fva = flux_variability_analysis(self._model,
                                                    fraction_of_optimum=0.99,
                                                    reactions=[self.target])
                self._processed_knockouts.loc[i] = [
                    knockouts,
                    len(knockouts), self.production[i], self.biomass[i],
                    fva.lower_bound(self.target),
                    fva.upper_bound(self.target)
                ]
            except SolveError:
                self._processed_knockouts.loc[i] = [
                    numpy.nan for _ in self._processed_knockouts.columns
                ]
Пример #15
0
        def test_weird_left_to_right_reaction_issue(self):

            model = Model("Toy Model")

            m1 = Metabolite("M1")
            d1 = Reaction("ex1")
            d1.add_metabolites({m1: -1})
            d1.upper_bound = 0
            d1.lower_bound = -1000
            # print d1.reaction, d1.lower_bound, d1.upper_bound
            model.add_reactions([d1])
            self.assertFalse(d1.reversibility)
            self.assertEqual(d1.lower_bound, -1000)
            self.assertEqual(d1._lower_bound, -1000)
            self.assertEqual(d1.upper_bound, 0)
            self.assertEqual(d1._upper_bound, 0)
            with TimeMachine() as tm:
                d1.knock_out(time_machine=tm)
                self.assertEqual(d1.lower_bound, 0)
                self.assertEqual(d1._lower_bound, 0)
                self.assertEqual(d1.upper_bound, 0)
                self.assertEqual(d1._upper_bound, 0)
            self.assertEqual(d1.lower_bound, -1000)
            self.assertEqual(d1._lower_bound, -1000)
            self.assertEqual(d1.upper_bound, 0)
            self.assertEqual(d1._upper_bound, 0)
Пример #16
0
 def test_knockout(self):
     original_bounds = dict()
     for reaction in self.model.reactions:
         original_bounds[reaction.id] = (reaction.lower_bound,
                                         reaction.upper_bound)
         reaction.knock_out()
         self.assertEqual(reaction.lower_bound, 0)
         self.assertEqual(reaction.upper_bound, 0)
     for k, (lb, ub) in six.iteritems(original_bounds):
         self.model.reactions.get_by_id(k).lower_bound = lb
         self.model.reactions.get_by_id(k).upper_bound = ub
     for reaction in self.model.reactions:
         self.assertEqual(reaction.lower_bound,
                          original_bounds[reaction.id][0])
         self.assertEqual(reaction.upper_bound,
                          original_bounds[reaction.id][1])
     with TimeMachine() as tm:
         for reaction in self.model.reactions:
             original_bounds[reaction.id] = (reaction.lower_bound,
                                             reaction.upper_bound)
             reaction.knock_out(time_machine=tm)
             self.assertEqual(reaction.lower_bound, 0)
             self.assertEqual(reaction.upper_bound, 0)
     for reaction in self.model.reactions:
         self.assertEqual(reaction.lower_bound,
                          original_bounds[reaction.id][0])
         self.assertEqual(reaction.upper_bound,
                          original_bounds[reaction.id][1])
Пример #17
0
 def test_with_statement(self):
     l = [1, 2, 3, 4]
     with TimeMachine() as tm:
         tm(do=partial(l.append, 33), undo=partial(l.pop))
         tm(do=partial(l.append, 66), undo=partial(l.pop))
         tm(do=partial(l.append, 99), undo=partial(l.pop))
     assert l == [1, 2, 3, 4]
Пример #18
0
def find_blocked_reactions(model):
    """Determine reactions that cannot carry steady-state flux.

    Parameters
    ----------
    model: SolverBasedModel

    Returns
    -------
    list
        A list of reactions.

    """
    with TimeMachine() as tm:
        for exchange in model.exchanges:
            tm(do=partial(setattr, exchange, 'lower_bound', -999999),
               undo=partial(setattr, exchange, 'lower_bound',
                            exchange.lower_bound))
            tm(do=partial(setattr, exchange, 'upper_bound', 999999),
               undo=partial(setattr, exchange, 'upper_bound',
                            exchange.upper_bound))
        fva_solution = flux_variability_analysis(model)
    return [
        model.reactions.get_by_id(id) for id in fva_solution.data_frame.query(
            'upper_bound == lower_bound == 0').index
    ]
Пример #19
0
def fba(model, objective=None, reactions=None, *args, **kwargs):
    """Flux Balance Analysis.

    Parameters
    ----------
    model: SolverBasedModel
    objective: a valid objective - see SolverBaseModel.objective (optional)

    Returns
    -------
    FluxDistributionResult
        Contains the result of the linear solver.

    """
    with TimeMachine() as tm:
        if objective is not None:
            tm(do=partial(setattr, model, 'objective', objective),
               undo=partial(setattr, model, 'objective', model.objective))
        solution = model.solve()
        if reactions is not None:
            result = FluxDistributionResult(
                {r: solution.get_primal_by_id(r)
                 for r in reactions}, solution.f)
        else:
            result = FluxDistributionResult.from_solution(solution)
        return result
Пример #20
0
    def test_room_shlomi_2005(self, toy_model):
        original_objective = toy_model.objective
        reference = {
            "b1": 10,
            "v1": 10,
            "v2": 5,
            "v3": 0,
            "v4": 0,
            "v5": 0,
            "v6": 5,
            "b2": 5,
            "b3": 5
        }
        expected = {
            'b1': 10.0,
            'b2': 5.0,
            'b3': 5.0,
            'v1': 10.0,
            'v2': 5.0,
            'v3': 0.0,
            'v4': 5.0,
            'v5': 5.0,
            'v6': 0.0
        }
        with TimeMachine() as tm:
            toy_model.reactions.v6.knock_out(tm)
            result = room(toy_model, reference=reference, delta=0, epsilon=0)

        for k in reference.keys():
            assert abs(expected[k] - result.fluxes[k]) < 0.1, "%s: %f | %f"
        assert toy_model.objective is original_objective
Пример #21
0
    def essential_reactions(self, threshold=1e-6):
        """Return a list of essential reactions.

        Parameters
        ----------
        threshold : float (default 1e-6)
            Minimal objective flux to be considered viable.

        Returns
        -------
        list
            List of essential reactions
        """
        essential = []
        try:
            solution = self.solve()

            for reaction_id, flux in six.iteritems(solution.fluxes):
                if abs(flux) > 0:
                    reaction = self.reactions.get_by_id(reaction_id)
                    with TimeMachine() as tm:
                        reaction.knock_out(time_machine=tm)
                        try:
                            sol = self.solve()
                        except Infeasible:
                            essential.append(reaction)
                        else:
                            if sol.f < threshold:
                                essential.append(reaction)

        except SolveError as e:
            logger.error('Cannot determine essential reactions for un-optimal model.')
            raise e

        return essential
Пример #22
0
    def __call__(self, strategy):
        max_evaluations = 20000

        if self.debug:
            max_evaluations = 1000

        (model, pathway, aerobic) = (strategy[1], strategy[2], strategy[3])
        model = model.copy()
        assert isinstance(model, SolverBasedModel)
        assert isinstance(pathway, PathwayResult)
        assert isinstance(aerobic, bool)

        with TimeMachine() as tm:
            if not aerobic and 'EX_o2_e' in model.reactions:
                model.reactions.EX_o2_e.change_bounds(lb=0, time_machine=tm)
            pathway.apply(model, tm)
            model.objective = model.biomass
            opt_gene = OptGene(model=model, plot=False)
            designs = opt_gene.run(target=pathway.product.id,
                                   biomass=model.biomass,
                                   substrate=model.carbon_source,
                                   max_evaluations=max_evaluations,
                                   max_knockouts=15)

            return designs
Пример #23
0
    def _production_envelope_inner(self, point):
        with TimeMachine() as tm:
            for (reaction, coordinate) in zip(self.variable_reactions, point):
                reaction.change_bounds(coordinate, coordinate, time_machine=tm)
            interval = []
            interval_carbon_yield = []
            interval_mass_yield = []
            tm(do=int,
               undo=partial(setattr, self.model.objective, 'direction',
                            self.model.objective.direction))

            self.model.objective.direction = 'min'
            flux, carbon_yield, mass_yield = self._interval_estimates()
            interval.append(flux)
            interval_carbon_yield.append(carbon_yield)
            interval_mass_yield.append(mass_yield)

            self.model.objective.direction = 'max'
            flux, carbon_yield, mass_yield = self._interval_estimates()
            interval.append(flux)
            interval_carbon_yield.append(carbon_yield)
            interval_mass_yield.append(mass_yield)

        intervals = tuple(interval) + tuple(interval_carbon_yield) + tuple(
            interval_mass_yield)
        return point + intervals
Пример #24
0
 def display_on_map(self, index=0, map_name=None, palette="YlGnBu"):
     with TimeMachine() as tm:
         for ko in self.data_frame.loc[index, "reactions"]:
             self._model.reactions.get_by_id(ko).knock_out(tm)
         fluxes = self._simulation_method(self._model,
                                          **self._simulation_kwargs)
         fluxes.display_on_map(map_name=map_name, palette=palette)
Пример #25
0
        def test_room_shlomi_2005(self):
            reference = {
                "b1": -10,
                "v1": 10,
                "v2": 5,
                "v3": 0,
                "v4": 0,
                "v5": 0,
                "v6": 5,
                "b2": 5,
                "b3": 5
            }
            TOY_MODEL_PAPIN_2004.solver = self.model.solver.interface
            with TimeMachine() as tm:
                TOY_MODEL_PAPIN_2004.reactions.v6.knock_out(tm)
                result = room(TOY_MODEL_PAPIN_2004,
                              reference=reference,
                              delta=0,
                              epsilon=0)

            self.assertEquals(
                result.fluxes, {
                    'b1': 10.0,
                    'b2': 5.0,
                    'b3': 5.0,
                    'v1': 5.0,
                    'v2': 5.0,
                    'v3': 0.0,
                    'v4': 5.0,
                    'v5': 5.0,
                    'v6': 0.0
                })
Пример #26
0
    def __call__(self, strategy):
        points = 50
        surface_only = False
        if self.debug:
            points = 5
            surface_only = True

        (model, pathway, aerobic) = (strategy[1], strategy[2], strategy[3])
        model = model.copy()
        assert isinstance(model, SolverBasedModel)
        assert isinstance(pathway, PathwayResult)
        assert isinstance(aerobic, bool)

        with TimeMachine() as tm:
            if not aerobic and 'EX_o2_e' in model.reactions:
                model.reactions.EX_o2_e.change_bounds(lb=0, time_machine=tm)

            pathway.apply(model, tm)
            model.objective = model.biomass
            diff_fva = DifferentialFVA(design_space_model=model,
                                       objective=pathway.product.id,
                                       variables=[model.biomass],
                                       points=points)
            designs = diff_fva.run(improvements_only=True,
                                   surface_only=surface_only)

            return designs
Пример #27
0
 def _simulate(self, reactions):
     with TimeMachine() as tm:
         for reaction in reactions:
             reaction.knock_out(time_machine=tm)
         solution = self.simulation_method(self.model,
                                           reference=self.reference)
         return solution
Пример #28
0
    def evaluate_individual(self, individual):
        """
        Evaluates a single individual.

        Arguments
        ---------

        individual: set
            The encoded representation of a single individual.


        Returns
        -------
        fitness
            A single real value or a Pareto, depending on the number of objectives.
        """
        targets = self.decoder(individual)
        with TimeMachine() as tm:
            for target in targets:
                target.knock_out(time_machine=tm)
            try:
                solution = self.simulation_method(
                    self.model,
                    cache=self.cache,
                    volatile=False,
                    raw=True,
                    reactions=self.objective_function.reactions,
                    **self.simulation_kwargs)
                fitness = self.objective_function(self.model, solution,
                                                  targets)
            except SolveError as e:
                logger.debug(e)
                fitness = self.objective_function.worst_fitness()
            return fitness
Пример #29
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)
        ]
Пример #30
0
    def simulate_knockout(self, to_knockout, *args, **kwargs):
        cache = {"variables": {}, "constraints": {}, "first_run": True}

        with TimeMachine() as tm:
            to_knockout.knock_out(tm)
            return self._simulation_method(
                self._model, volatile=False, cache=cache, *args,
                **kwargs)[cache['original_objective']]
Пример #31
0
def process_reaction_swap_solution(model, solution, simulation_method,
                                   simulation_kwargs, biomass, target,
                                   substrate, objective_function, swap_pairs):
    """

    Arguments
    ---------

    model: SolverBasedModel
        A constraint-based model
    solution: tuple - (reactions, knockouts)
        The output of a decoder
    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.
    swap_pairs:
        The metabolites to swap

    Returns
    -------

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

    with TimeMachine() as tm:
        reactions = [model.reactions.get_by_id(rid) for rid in solution]
        for reaction in reactions:
            reaction.swap_cofactors(tm, swap_pairs)

        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 [
            solution,
            fva.lower_bound(target),
            fva.upper_bound(target), flux_dist[target], flux_dist[biomass],
            target_yield,
            objective_function(model, flux_dist, reactions)
        ]
Пример #32
0
def draw_knockout_result(model, map_name, simulation_method, knockouts, *args, **kwargs):
    tm = TimeMachine()

    try:
        for reaction in model._ids_to_reactions(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))

        solution = simulation_method(model, *args, **kwargs).x_dict
        tm.reset()

        return Builder(map_name, reaction_data=solution)

    except Exception as e:
        tm.reset()
        raise e
Пример #33
0
    def __call__(self, strategy):
        (model, pathway) = (strategy[1], strategy[2])
        with TimeMachine() as tm:
            pathway.plug_model(model, tm)
            opt_gene = DifferentialFVA(design_space_model=model,
                                       objective=pathway.product.id)
            designs = opt_gene.run()

            return designs, pathway
Пример #34
0
    def test_reaction_knockout_target(self):
        knockout_target = ReactionKnockoutTarget("ACALD")
        with TimeMachine() as tm:
            knockout_target.apply(self.model, time_machine=tm)
            self.assertEqual(self.model.reactions.ACALD.lower_bound, 0)
            self.assertEqual(self.model.reactions.ACALD.upper_bound, 0)

        self.assertEqual(self.model.reactions.ACALD.lower_bound, -1000)
        self.assertEqual(self.model.reactions.ACALD.upper_bound, 1000)
Пример #35
0
def reaction_component_production(model, reaction):
    tm = TimeMachine()
    for metabolite in reaction.metabolites:
        test = Reaction("EX_%s_temp" % metabolite.id)
        test._metabolites[metabolite] = -1
        # hack frozen set from cobrapy to be able to add a reaction
        metabolite._reaction = set(metabolite._reaction)
        tm(do=partial(model.add_reactions, [test]),
           undo=partial(model.remove_reactions, [test]))
        tm(do=partial(setattr, model, 'objective', test.id),
           undo=partial(setattr, model, 'objective', model.objective))
        try:
            print(metabolite.id, "= ", model.solve().f)
        except SolveError:
            print(metabolite,
                  " cannot be produced (reactions: %s)" % metabolite.reactions)
        finally:
            tm.reset()
Пример #36
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
Пример #37
0
def _cycle_free_fva(model, reactions=None, sloppy=True, sloppy_bound=666):
    """Cycle free flux-variability analysis. (http://cran.r-project.org/web/packages/sybilcycleFreeFlux/index.html)

    Parameters
    ----------
    model : SolverBasedModel
    reactions : list
        List of reactions whose flux-ranges should be determined.
    sloppy : boolean, optional
        If true, only fluxes v with abs(v) > sloppy_bound are checked to be futile cycles (defaults to True).
    sloppy_bound : int, optional
        The threshold bound used by sloppy (defaults to the number of the beast).
    """
    cycle_count = 0
    try:
        original_objective = copy(model.objective)
        if reactions is None:
            reactions = model.reactions
        else:
            reactions = model._ids_to_reactions(reactions)
        fva_sol = OrderedDict()
        for reaction in reactions:
            fva_sol[reaction.id] = dict()
            model.objective = reaction
            model.objective.direction = 'min'
            try:
                solution = model.solve()
            except Unbounded:
                fva_sol[reaction.id]['lower_bound'] = -numpy.inf
                continue
            except Infeasible:
                fva_sol[reaction.id]['lower_bound'] = 0
                continue
            except Exception as e:
                raise e
            bound = solution.f
            if sloppy and abs(bound) < sloppy_bound:
                fva_sol[reaction.id]['lower_bound'] = bound
            else:
                logger.debug('Determine if {} with bound {} is a cycle'.format(reaction.id, bound))
                v0_fluxes = solution.x_dict
                v1_cycle_free_fluxes = remove_infeasible_cycles(model, v0_fluxes)
                if abs(v1_cycle_free_fluxes[reaction.id] - bound) < 10 ** -6:
                    fva_sol[reaction.id]['lower_bound'] = bound
                else:
                    logger.debug('Cycle detected: {}'.format(reaction.id))
                    cycle_count += 1
                    v2_one_cycle_fluxes = remove_infeasible_cycles(model, v0_fluxes, fix=[reaction.id])
                    tm = TimeMachine()
                    for key, v1_flux in six.iteritems(v1_cycle_free_fluxes):
                        if v1_flux == 0 and v2_one_cycle_fluxes[key] != 0:
                            knockout_reaction = model.reactions.get_by_id(key)
                            tm(do=partial(setattr, knockout_reaction, 'lower_bound', 0.),
                               undo=partial(setattr, knockout_reaction, 'lower_bound', knockout_reaction.lower_bound))
                            tm(do=partial(setattr, knockout_reaction, 'upper_bound', 0.),
                               undo=partial(setattr, knockout_reaction, 'upper_bound', knockout_reaction.lower_bound))
                    model.objective.direction = 'min'
                    try:
                        solution = model.solve()
                    except Unbounded:
                        fva_sol[reaction.id]['lower_bound'] = -numpy.inf
                    except Infeasible:
                        fva_sol[reaction.id]['lower_bound'] = 0
                    else:
                        fva_sol[reaction.id]['lower_bound'] = solution.f
                    finally:
                        tm.reset()
        for reaction in reactions:
            model.objective = reaction
            model.objective.direction = 'max'
            try:
                solution = model.solve()
            except Unbounded:
                fva_sol[reaction.id]['upper_bound'] = numpy.inf
                continue
            except Infeasible:
                fva_sol[reaction.id]['upper_bound'] = 0
                continue
            except Exception as e:
                raise e
            else:
                bound = solution.f
                if sloppy and abs(bound) < sloppy_bound:
                    fva_sol[reaction.id]['upper_bound'] = bound
                else:
                    logger.debug('Determine if {} with bound {} is a cycle'.format(reaction.id, bound))
                    v0_fluxes = solution.x_dict
                    v1_cycle_free_fluxes = remove_infeasible_cycles(model, v0_fluxes)

                    if abs(v1_cycle_free_fluxes[reaction.id] - bound) < 10 ** -6:
                        fva_sol[reaction.id]['upper_bound'] = v0_fluxes[reaction.id]
                    else:
                        logger.debug('Cycle detected: {}'.format(reaction.id))
                        cycle_count += 1
                        v2_one_cycle_fluxes = remove_infeasible_cycles(model, v0_fluxes, fix=[reaction.id])
                        tm = TimeMachine()
                        for key, v1_flux in six.iteritems(v1_cycle_free_fluxes):
                            if v1_flux == 0 and v2_one_cycle_fluxes[key] != 0:
                                knockout_reaction = model.reactions.get_by_id(key)
                                tm(do=partial(setattr, knockout_reaction, 'lower_bound', 0.),
                                   undo=partial(setattr, knockout_reaction, 'lower_bound',
                                                knockout_reaction.lower_bound))
                                tm(do=partial(setattr, knockout_reaction, 'upper_bound', 0.),
                                   undo=partial(setattr, knockout_reaction, 'upper_bound',
                                                knockout_reaction.lower_bound))
                        model.objective.direction = 'max'
                        try:
                            solution = model.solve()
                        except Unbounded:
                            fva_sol[reaction.id]['upper_bound'] = numpy.inf
                        except Infeasible:
                            fva_sol[reaction.id]['upper_bound'] = 0
                        else:
                            fva_sol[reaction.id]['upper_bound'] = solution.f
                        finally:
                            tm.reset()
        df = pandas.DataFrame.from_dict(fva_sol, orient='index')
        lb_higher_ub = df[df.lower_bound > df.upper_bound]
        assert ((
                lb_higher_ub.lower_bound - lb_higher_ub.upper_bound) < 1e-6).all()  # Assert that these cases really only numerical artifacts
        df.lower_bound[lb_higher_ub.index] = df.upper_bound[lb_higher_ub.index]
    finally:
        model.objective = original_objective
    return df
Пример #38
0
 def setUp(self):
     self.tm = TimeMachine()