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
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)
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
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]
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
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])
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])
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']
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
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
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
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()
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 ]
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)
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])
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]
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 ]
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
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
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
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
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
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)
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 })
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
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
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
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) ]
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']]
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) ]
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
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
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)
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()
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
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
def setUp(self): self.tm = TimeMachine()