def test_change_coefficient(self): solver = self.solver c = Metabolite("c") c._bound = 6 x = Reaction("x") x.lower_bound = 1. y = Reaction("y") y.lower_bound = 0. x.add_metabolites({c: 1}) #y.add_metabolites({c: 1}) z = Reaction("z") z.add_metabolites({c: 1}) z.objective_coefficient = 1 m = Model("test_model") m.add_reactions([x, y, z]) # change an existing coefficient lp = solver.create_problem(m) solver.solve_problem(lp) sol1 = solver.format_solution(lp, m) solver.change_coefficient(lp, 0, 0, 2) solver.solve_problem(lp) sol2 = solver.format_solution(lp, m) self.assertAlmostEqual(sol1.f, 5.0) self.assertAlmostEqual(sol2.f, 4.0) # change a new coefficient z.objective_coefficient = 0. y.objective_coefficient = 1. lp = solver.create_problem(m) solver.change_coefficient(lp, 0, 1, 2) solver.solve_problem(lp) solution = solver.format_solution(lp, m) self.assertAlmostEqual(solution.x_dict["y"], 2.5)
def test_solve_mip(self): solver = self.solver if not hasattr(solver, "_SUPPORTS_MILP") or not solver._SUPPORTS_MILP: self.skipTest("no milp support") cobra_model = Model('MILP_implementation_test') constraint = Metabolite("constraint") constraint._bound = 2.5 x = Reaction("x") x.lower_bound = 0. x.objective_coefficient = 1. x.add_metabolites({constraint: 2.5}) y = Reaction("y") y.lower_bound = 0. y.objective_coefficient = 1. y.add_metabolites({constraint: 1.}) cobra_model.add_reactions([x, y]) float_sol = solver.solve(cobra_model) # add an integer constraint y.variable_kind = "integer" int_sol = solver.solve(cobra_model) self.assertAlmostEqual(float_sol.f, 2.5) self.assertAlmostEqual(float_sol.x_dict["y"], 2.5) self.assertEqual(int_sol.status, "optimal") self.assertAlmostEqual(int_sol.f, 2.2) self.assertAlmostEqual(int_sol.x_dict["y"], 2.0)
def LP7(model,the_reactions=None,epsilon=1e-3,solver=None): model_lp7 = model.copy() for reaction in model_lp7.reactions: reaction.objective_coefficient = 0 if the_reactions is None: the_reactions = [r.id for r in model_lp7.reactions] if not hasattr(list(the_reactions)[0], 'id'): the_reactions = map(model_lp7.reactions.get_by_id,the_reactions) for reaction in the_reactions: dummy_reaction = Reaction("dummy_rxn_" + reaction.id) dummy_reaction.lower_bound = 0 dummy_reaction.upper_bound = epsilon dummy_reaction.objective_coefficient = 1 model_lp7.add_reaction(dummy_reaction) dummy_metabolite = Metabolite("dummy_met_" + reaction.id) dummy_metabolite._constraint_sense = "L" dummy_metabolite._bound = 0 reaction.add_metabolites({dummy_metabolite: -1}) dummy_reaction.add_metabolites({dummy_metabolite: 1}) model_lp7.optimize(solver=solver) if model_lp7.solution is None or model_lp7.solution.x_dict is None: print "INFEASIBLE LP7" return {} return dict([(k,v) for k,v in model_lp7.solution.x_dict.items() if not k.startswith('dummy_')])
def LP7(model, the_reactions=None, epsilon=1e-3, solver=None): model_lp7 = model.copy() for reaction in model_lp7.reactions: reaction.objective_coefficient = 0 if the_reactions is None: the_reactions = [r.id for r in model_lp7.reactions] if not hasattr(list(the_reactions)[0], 'id'): the_reactions = map(model_lp7.reactions.get_by_id, the_reactions) for reaction in the_reactions: dummy_reaction = Reaction("dummy_rxn_" + reaction.id) dummy_reaction.lower_bound = 0 dummy_reaction.upper_bound = epsilon dummy_reaction.objective_coefficient = 1 model_lp7.add_reaction(dummy_reaction) dummy_metabolite = Metabolite("dummy_met_" + reaction.id) dummy_metabolite._constraint_sense = "L" dummy_metabolite._bound = 0 reaction.add_metabolites({dummy_metabolite: -1}) dummy_reaction.add_metabolites({dummy_metabolite: 1}) model_lp7.optimize(solver=solver) if model_lp7.solution is None or model_lp7.solution.x_dict is None: print "INFEASIBLE LP7" return {} return dict([(k, v) for k, v in model_lp7.solution.x_dict.items() if not k.startswith('dummy_')])
def test_distance_based_on_molecular_formula( self): # from network_analysis.util met1 = Metabolite("H2O", formula="H2O") met2 = Metabolite("H2O2", formula="H2O2") met3 = Metabolite("C6H12O6", formula="C6H12O6") self.assertEqual( distance_based_on_molecular_formula(met1, met2, normalize=False), 1) self.assertEqual( distance_based_on_molecular_formula(met1, met2, normalize=True), 1. / 7) self.assertEqual( distance_based_on_molecular_formula(met2, met3, normalize=False), 20) self.assertEqual( distance_based_on_molecular_formula(met2, met3, normalize=True), 20. / 28) self.assertEqual( distance_based_on_molecular_formula(met1, met3, normalize=False), 21) self.assertEqual( distance_based_on_molecular_formula(met1, met3, normalize=True), 21. / 27)
def test_iadd(self): model = self.model PGI = model.reactions.PGI EX_h2o = model.reactions.EX_h2o_e original_PGI_gpr = PGI.gene_reaction_rule PGI += EX_h2o self.assertEqual(PGI.gene_reaction_rule, original_PGI_gpr) self.assertEqual(PGI.metabolites[model.metabolites.h2o_e], -1.0) # original should not have changed self.assertEqual(EX_h2o.gene_reaction_rule, '') self.assertEqual(EX_h2o.metabolites[model.metabolites.h2o_e], -1.0) # what about adding a reaction not in the model new_reaction = Reaction("test") new_reaction.add_metabolites({Metabolite("A"): -1, Metabolite("B"): 1}) PGI += new_reaction self.assertEqual(PGI.gene_reaction_rule, original_PGI_gpr) self.assertEqual(len(PGI.gene_reaction_rule), 5) # and vice versa new_reaction += PGI self.assertEqual(len(new_reaction.metabolites), 5) # not 7 self.assertEqual(len(new_reaction.genes), 1) self.assertEqual(new_reaction.gene_reaction_rule, original_PGI_gpr) # what about combining 2 gpr's model.reactions.ACKr += model.reactions.ACONTa self.assertEqual(model.reactions.ACKr.gene_reaction_rule, "(b2296 or b3115 or b1849) and (b0118 or b1276)") self.assertEqual(len(model.reactions.ACKr.genes), 5)
def test_add_reactions(self): r1 = Reaction('r1') r1.add_metabolites({Metabolite('A'): -1, Metabolite('B'): 1}) r1.lower_bound, r1.upper_bound = -999999., 999999. r2 = Reaction('r2') r2.add_metabolites({ Metabolite('A'): -1, Metabolite('C'): 1, Metabolite('D'): 1 }) r2.lower_bound, r2.upper_bound = 0., 999999. r2.objective_coefficient = 3. self.model.add_reactions([r1, r2]) self.assertEqual(self.model.reactions[-2], r1) self.assertEqual(self.model.reactions[-1], r2) self.assertTrue( isinstance(self.model.reactions[-2].reverse_variable, self.model.solver.interface.Variable)) self.assertEqual( self.model.objective.expression.coeff( self.model.reactions. Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2. forward_variable), 1.) self.assertEqual( self.model.objective.expression.coeff( self.model.reactions. Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2. reverse_variable), -1.) self.assertEqual( self.model.objective.expression.coeff( self.model.reactions.r2.forward_variable), 3.) self.assertEqual( self.model.objective.expression.coeff( self.model.reactions.r2.reverse_variable), -3.)
def test_loopless(self): try: solver = get_solver_name(mip=True) except: self.skipTest("no MILP solver found") test_model = Model() test_model.add_metabolites(Metabolite("A")) test_model.add_metabolites(Metabolite("B")) test_model.add_metabolites(Metabolite("C")) EX_A = Reaction("EX_A") EX_A.add_metabolites({test_model.metabolites.A: 1}) DM_C = Reaction("DM_C") DM_C.add_metabolites({test_model.metabolites.C: -1}) v1 = Reaction("v1") v1.add_metabolites({test_model.metabolites.A: -1, test_model.metabolites.B: 1}) v2 = Reaction("v2") v2.add_metabolites({test_model.metabolites.B: -1, test_model.metabolites.C: 1}) v3 = Reaction("v3") v3.add_metabolites({test_model.metabolites.C: -1, test_model.metabolites.A: 1}) DM_C.objective_coefficient = 1 test_model.add_reactions([EX_A, DM_C, v1, v2, v3]) feasible_sol = construct_loopless_model(test_model).optimize() v3.lower_bound = 1 infeasible_sol = construct_loopless_model(test_model).optimize() self.assertEqual(feasible_sol.status, "optimal") self.assertEqual(infeasible_sol.status, "infeasible")
def test_add_metabolite(self): model = self.model reaction = model.reactions.get_by_id("PGI") reaction.add_metabolites({model.metabolites[0]: 1}) self.assertIn(model.metabolites[0], reaction._metabolites) fake_metabolite = Metabolite("fake") reaction.add_metabolites({fake_metabolite: 1}) self.assertIn(fake_metabolite, reaction._metabolites) self.assertTrue(model.metabolites.has_id("fake")) self.assertIs(model.metabolites.get_by_id("fake"), fake_metabolite) # test adding by string reaction.add_metabolites({"g6p_c": -1}) # already in reaction self.assertTrue( reaction._metabolites[model.metabolites.get_by_id("g6p_c")], -2) reaction.add_metabolites({"h_c": 1}) # not currently in reaction self.assertTrue( reaction._metabolites[model.metabolites.get_by_id("h_c")], 1) with self.assertRaises(KeyError): reaction.add_metabolites({"missing": 1}) # test adding to a new Reaction reaction = Reaction("test") self.assertEqual(len(reaction._metabolites), 0) reaction.add_metabolites({Metabolite("test_met"): -1}) self.assertEqual(len(reaction._metabolites), 1)
def test_bad_exchange(self, model): with pytest.raises(ValueError): m = Metabolite("baddy", compartment="nonsense") model.add_boundary(m, type="exchange") m = Metabolite("goody", compartment="e") rxn = model.add_boundary(m, type="exchange") assert isinstance(rxn, Reaction)
def test_find_dead_end_reactions(self, core_model): assert len(structural.find_dead_end_reactions(core_model)) == 0 met1 = Metabolite("fake_metabolite_1") met2 = Metabolite("fake_metabolite_2") reac = Reaction("fake_reac") reac.add_metabolites({met1: -1, met2: 1}) core_model.add_reaction(reac) assert structural.find_dead_end_reactions(core_model) == {reac}
def add_reaction(model, reaction_id, db, compartment='c'): """ Add a metacyc reaction id to a cobrapy model :param model: cobrapy model instance :param reaction_id: reaction identifier in metacyc :param db: dictionary db object :param compartment: compartment reactions takeplace in (default is "c") :return: tuple(reaction, added_metabolites) cobrapy Reaction and Metabolite instances """ metabolites = dict() reaction = Reaction(reaction_id) dbr = db['reactions'][reaction_id] for mid, coef in Counter(dbr['LEFT']).items(): mid = mid.replace('|', '') metabolites[mid] = coef for mid, coef in Counter(dbr['RIGHT']).items(): mid = mid.replace('|', '') metabolites[mid] = -1 * coef model.add_reactions([reaction]) added_metabolites = [] for mid in metabolites: if mid not in model.metabolites: try: cpd = db['compounds'][mid] except KeyError: # Handles missing metabolites cpd = {"COMMON-NAME": mid} m = Metabolite(id=mid) m.name = cpd['COMMON-NAME'] m.annotation = dict(metacyc_data=cpd) m.compartment = compartment model.add_metabolites([m]) added_metabolites.append(mid) reaction.add_metabolites(metabolites) if 'REACTION-DIRECTION' in dbr and dbr['REACTION-DIRECTION'] in [ 'LEFT-TO-RIGHT', 'PHYSIOL-LEFT-TO-RIGHT' ]: reaction.lower_bound = -1000.0 reaction.upper_bound = 0 elif 'REACTION-DIRECTION' in dbr and dbr['REACTION-DIRECTION'] in [ 'RIGHT-TO-LEFT', 'PHYSIOL-RIGHT-TO-LEFT' ]: reaction.lower_bound = 0 reaction.upper_bound = 1000.0 else: reaction.lower_bound = -1000.0 reaction.upper_bound = 1000.0 reaction.annotation = dict( metacyc_data=dbr) # TODO: Add enzyme identifiers return reaction, added_metabolites
def test_quadratic(self): solver = self.solver if not hasattr(solver, "set_quadratic_objective"): self.skipTest("no qp support") c = Metabolite("c") c._bound = 2 x = Reaction("x") x.objective_coefficient = -0.5 x.lower_bound = 0. y = Reaction("y") y.objective_coefficient = -0.5 y.lower_bound = 0. x.add_metabolites({c: 1}) y.add_metabolites({c: 1}) m = Model() m.add_reactions([x, y]) lp = self.solver.create_problem(m) quadratic_obj = scipy.sparse.eye(2) * 2 solver.set_quadratic_objective(lp, quadratic_obj) solver.solve_problem(lp, objective_sense="minimize") solution = solver.format_solution(lp, m) self.assertEqual(solution.status, "optimal") # Respecting linear objectives also makes the objective value 1. self.assertAlmostEqual(solution.f, 1.) self.assertAlmostEqual(solution.x_dict["y"], 1.) self.assertAlmostEqual(solution.x_dict["y"], 1.) # When the linear objectives are removed the objective value is 2. solver.change_variable_objective(lp, 0, 0.) solver.change_variable_objective(lp, 1, 0.) solver.solve_problem(lp, objective_sense="minimize") solution = solver.format_solution(lp, m) self.assertEqual(solution.status, "optimal") self.assertAlmostEqual(solution.f, 2.) # test quadratic from solve function solution = solver.solve(m, quadratic_component=quadratic_obj, objective_sense="minimize") self.assertEqual(solution.status, "optimal") self.assertAlmostEqual(solution.f, 1.) c._bound = 6 z = Reaction("z") x.objective_coefficient = 0. y.objective_coefficient = 0. z.lower_bound = 0. z.add_metabolites({c: 1}) m.add_reaction(z) solution = solver.solve(m, quadratic_component=scipy.sparse.eye(3), objective_sense="minimize") # should be 12 not 24 because 1/2 (V^T Q V) self.assertEqual(solution.status, "optimal") self.assertAlmostEqual(solution.f, 6) self.assertAlmostEqual(solution.x_dict["x"], 2, places=6) self.assertAlmostEqual(solution.x_dict["y"], 2, places=6) self.assertAlmostEqual(solution.x_dict["z"], 2, places=6)
def three_components_closed(base): """Returns a simple model with 3 metabolites in a closed system.""" met_a = Metabolite("A") met_b = Metabolite("B") met_c = Metabolite("C") rxn_1 = Reaction("R1", lower_bound=-1000, upper_bound=1000) rxn_1.add_metabolites({met_a: -1, met_b: 1}) rxn_2 = Reaction("R2", lower_bound=-1000, upper_bound=1000) rxn_2.add_metabolites({met_b: -1, met_c: 1}) base.add_reactions([rxn_1, rxn_2]) return base
def test_distance_based_on_molecular_formula(self): # from network_analysis.util met1 = Metabolite("H2O", formula="H2O") met2 = Metabolite("H2O2", formula="H2O2") met3 = Metabolite("C6H12O6", formula="C6H12O6") assert distance_based_on_molecular_formula(met1, met2, normalize=False) == 1 assert distance_based_on_molecular_formula(met1, met2, normalize=True) == 1. / 7 assert distance_based_on_molecular_formula(met2, met3, normalize=False) == 20 assert distance_based_on_molecular_formula(met2, met3, normalize=True) == 20. / 28 assert distance_based_on_molecular_formula(met1, met3, normalize=False) == 21 assert distance_based_on_molecular_formula(met1, met3, normalize=True) == 21. / 27
def x2_cycle_closed(base): x1 = Metabolite("x1") x2 = Metabolite("x2") x3 = Metabolite("x3") x4 = Metabolite("x4") x5 = Metabolite("x5") rxn_1 = Reaction("R1", lower_bound=-1000, upper_bound=1000) rxn_1.add_metabolites({x1: -1, x2: -1, x3: 1}) rxn_2 = Reaction("R2", lower_bound=-1000, upper_bound=1000) rxn_2.add_metabolites({x3: -1, x4: 1}) rxn_3 = Reaction("R3", lower_bound=-1000, upper_bound=1000) rxn_3.add_metabolites({x4: -1, x5: 1, x2: 1}) base.add_reactions([rxn_1, rxn_2, rxn_3]) return base
def test_inequality(self): # The space enclosed by the constraints is a 2D triangle with # vertexes as (3, 0), (1, 2), and (0, 1) solver = self.solver # c1 encodes y - x > 1 ==> y > x - 1 # c2 encodes y + x < 3 ==> y < 3 - x c1 = Metabolite("c1") c2 = Metabolite("c2") x = Reaction("x") x.lower_bound = 0 y = Reaction("y") y.lower_bound = 0 x.add_metabolites({c1: -1, c2: 1}) y.add_metabolites({c1: 1, c2: 1}) c1._bound = 1 c1._constraint_sense = "G" c2._bound = 3 c2._constraint_sense = "L" m = Model() m.add_reactions([x, y]) # test that optimal values are at the vertices m.change_objective("x") self.assertAlmostEqual(solver.solve(m).f, 1.0) self.assertAlmostEqual(solver.solve(m).x_dict["y"], 2.0) m.change_objective("y") self.assertAlmostEqual(solver.solve(m).f, 3.0) self.assertAlmostEqual( solver.solve(m, objective_sense="minimize").f, 1.0)
def LP9(model,K,P,weights={},epsilon=1e-4,solver=None,scaling_factor=1e3,use_milp=False): model = model.copy() scaling_factor = 1/epsilon for reaction in model.reactions: reaction.objective_coefficient = 0 reaction.lower_bound *= scaling_factor reaction.upper_bound *= scaling_factor for reaction in P: reaction = model.reactions.get_by_id(reaction) dummy_reaction = Reaction("dummy_rxn_" + reaction.id) dummy_reaction.lower_bound = 0. if use_milp: dummy_reaction.upper_bound = 1. dummy_reaction.variable_kind = 'integer' else: dummy_reaction.upper_bound = 1000. dummy_reaction.objective_coefficient = weights[reaction.id] model.add_reaction(dummy_reaction) dummy_metabolite = Metabolite("dummy_met_ub_" + reaction.id) dummy_metabolite._constraint_sense = "L" dummy_metabolite._bound = 0. reaction.add_metabolites({dummy_metabolite: 1.}) if use_milp: dummy_reaction.add_metabolites({dummy_metabolite: -1000}) else: dummy_reaction.add_metabolites({dummy_metabolite: -1}) dummy_metabolite = Metabolite("dummy_met_lb_" + reaction.id) dummy_metabolite._constraint_sense = "L" dummy_metabolite._bound = 0. reaction.add_metabolites({dummy_metabolite: -1.}) if use_milp: dummy_reaction.add_metabolites({dummy_metabolite: -1000.0}) else: dummy_reaction.add_metabolites({dummy_metabolite: -1.}) for reaction in K: reaction = model.reactions.get_by_id(reaction) dummy_metabolite = Metabolite("dummy_met_lb_" + reaction.id) dummy_metabolite._constraint_sense = "G" dummy_metabolite._bound = 1. reaction.add_metabolites({dummy_metabolite: 1.}) model.optimize(objective_sense='minimize',solver=solver) if model.solution is None or model.solution.x_dict is None: print "INFEASIBLE LP9" return {} return dict([(k,v) for k,v in model.solution.x_dict.items() if not k.startswith('dummy_')])
def __swap_modelseed_compound(self, model_metabolite: Metabolite, new_compound_ontology_id: int): """ Method to swap a metabolite in the Model SEED database format. This method tries to find the Model SEED format of the new compound. If it does not find, it will change into an arbitrary id with the Model SEED or the Ontology format. :param Model.Metabolite model_metabolite: metabolite to be replaced. :param int new_compound_ontology_id: ontology identifier of the metabolite that will replace the other :return: """ old_inchikey = "" if "inchi_key" in model_metabolite.annotation.keys(): old_inchikey = model_metabolite.annotation["inchi_key"] old_aliases = AnnotationUtils.get_annotation_from_cobra_annotation( model_metabolite) old_id = model_metabolite.id model_metabolite.annotation = {} compound_container = self.__compounds_ontology.get_node_by_ont_id( new_compound_ontology_id) new_aliases = self.__compoundsIdConverter.get_all_aliases_by_modelSeedID( compound_container.model_seed_id) annotation = AnnotationUtils.get_compound_annotation_format_by_aliases( new_aliases) model_metabolite.annotation = annotation new_inchikey = "" if not compound_container.generic: model_metabolite.annotation[ "inchi_key"] = compound_container.inchikey new_inchikey = compound_container.inchikey model_metabolite.annotation["smiles"] = compound_container.smiles model_metabolite.formula = compound_container.formula model_metabolite.charge = compound_container.charge compartment = model_metabolite.compartment db_id = compound_container.model_seed_id model_metabolite.name = compound_container.name if db_id: self.__check_if_id_is_used_in_model_and_delete_it( compound_container.model_seed_id + "_" + compartment) model_metabolite.id = compound_container.model_seed_id + "_" + compartment self.mapper.update_maps(old_inchikey, new_inchikey, old_id, model_metabolite.id, new_compound_ontology_id, old_aliases, new_aliases) else: self.__change_boimmg_format_metabolite(model_metabolite, compound_container)
def cad_reaction(core_model): reaction = Reaction(id="CAD", name="Cis-Aconitate Decarboxylase") acon = core_model.metabolites.acon_DASH_C_c co2_c = core_model.metabolites.co2_c ita_c = Metabolite(id="ita_c", name="Itaconate", compartment="c") reaction.add_metabolites({acon: -1, co2_c: 1, ita_c: 1}) return reaction
def test_one_left_to_right_reaction_set_positive_ub(self): model = Model("Toy Model") m1 = Metabolite("M1") d1 = Reaction("ex1") d1.add_metabolites({m1: -1}) d1.upper_bound = 0 d1.lower_bound = -1000 model.add_reactions([d1]) self.assertEqual(d1.reverse_variable.lb, 0) self.assertEqual(d1.reverse_variable.ub, 1000) self.assertEqual(d1._lower_bound, -1000) self.assertEqual(d1.lower_bound, -1000) self.assertEqual(d1._upper_bound, 0) self.assertEqual(d1.upper_bound, 0) self.assertEqual(d1.forward_variable.lb, 0) self.assertEqual(d1.forward_variable.ub, 0) d1.upper_bound = .1 self.assertEqual(d1.forward_variable.lb, 0) self.assertEqual(d1.forward_variable.ub, .1) self.assertEqual(d1.reverse_variable.lb, 0) self.assertEqual(d1.reverse_variable.ub, 1000) self.assertEqual(d1._lower_bound, -1000) self.assertEqual(d1.upper_bound, .1) self.assertEqual(d1._lower_bound, -1000) self.assertEqual(d1.upper_bound, .1)
def test_add_metabolites_combine_true(self): test_metabolite = Metabolite('test') for reaction in self.model.reactions: reaction.add_metabolites({test_metabolite: -66}, combine=True) self.assertEqual(reaction.metabolites[test_metabolite], -66) self.assertIn(-66. * reaction.forward_variable, self.model.solver.constraints['test'].expression) self.assertIn(66. * reaction.reverse_variable, self.model.solver.constraints['test'].expression) already_included_metabolite = list( reaction.metabolites.keys())[0] previous_coefficient = reaction.get_coefficient( already_included_metabolite.id) reaction.add_metabolites({already_included_metabolite: 10}, combine=True) new_coefficient = previous_coefficient + 10 self.assertEqual( reaction.metabolites[already_included_metabolite], new_coefficient) self.assertIn( new_coefficient * reaction.forward_variable, self.model.solver.constraints[ already_included_metabolite.id].expression) self.assertIn( -1 * new_coefficient * reaction.reverse_variable, self.model.solver.constraints[ already_included_metabolite.id].expression)
def FDA(kegg_reactions): ###kegg_reactions = ['R00509'] model_reactions = [] model_metabolites = [] for item1 in model.reactions: model_reactions.append(item1.id) for item2 in model.metabolites: model_metabolites.append(item2.id) for k_id in kegg_reactions: if k_id in bigg_reactions.keys(): if bigg_reactions[k_id]['id'] not in model_reactions: reaction = Reaction(bigg_reactions[k_id]['id']) print(reaction.id) reaction.name = '' reaction.subsystem = '' reaction.lower_bound = bigg_reactions[k_id][ 'lower_bound'] # This is the default reaction.upper_bound = bigg_reactions[k_id][ 'upper_bound'] # This is the default for key in bigg_reactions[k_id]['metabolites']: if key in model_metabolites: reaction.add_metabolites({ model.metabolites.get_by_id(key): bigg_reactions[k_id]['metabolites'][key] }) else: a = Metabolite(key, formula='', name='', compartment='') reaction.add_metabolites( {a: bigg_reactions[k_id]['metabolites'][key]}) reaction.gene_reaction_rule = bigg_reactions[k_id][ 'gene_reaction_rule'] model.add_reactions([reaction])
def createTokens(model,reactionmap): from cobra import Reaction from cobra import Metabolite ''' Compares a CobraPy model and a reaction map. If several model reactions are associated with the same experimental reaction, a token reaction is created whose flux will equal a linear combination of those reactions (the token flux). This token reaction can be used as a decision variable during quadratic optimization attempting to match the token flux to that of the experimental reaction. Noe that limiting the token flux to zero will prevent any flux through the separate reactions. ''' for linkdict in reactionmap: if len(linkdict['modrxns']) > 1: experimental_r_id = linkdict['exprxns'][0]['rxid'] token_id = 't_{exprxnid}'.format(exprxnid = experimental_r_id) new_token_reaction = Reaction(token_id) new_token_reaction.name = 'Token exchange reaction for experimental reaction {exprxnid}'.format(exprxnid = experimental_r_id) new_token_reaction.lower_bound = -1000 new_token_reaction.upper_bound = 1000 new_token_metabolite = Metabolite(token_id,name = 'Token metabolite for experimental reaction {exprxnid}'.format(exprxnid = experimental_r_id),compartment='c') new_token_reaction.add_metabolites({new_token_metabolite: -1.0}) model.add_reactions(new_token_reaction) for dictionary in linkdict['modrxns']: modelreaction = model.reactions.get_by_id(dictionary['rxid']) modelreaction.add_metabolites({new_token_metabolite: float(dictionary['coef'])}) return model
def add_metabolite(self, m_id, m_name, compartment): if m_id not in self.metabolites: ############## # model_data # ############## self.metabolites[m_id] = m_name self.listed_metabolites.append(m_id) self.metabolite_position[m_id] = len(self.listed_metabolites) - 1 self.compartment_metabolites[compartment].add(m_id) ######### # cobra # ######### if compartment not in self.model.compartments: self.model.compartments[compartment] = compartment metabolite = Metabolite(m_id, formula="", name=m_name, compartment=compartment) self.model.metabolites.append(metabolite) return 1 return 0
def test_reaction_delete(self): model = self.model old_reaction_count = len(model.reactions) tmp_metabolite = Metabolite("testing") # Delete without removing orphan model.reactions[0].add_metabolites({tmp_metabolite: 1}) self.assertEqual(len(tmp_metabolite.reactions), 1) model.reactions[0].delete(remove_orphans=False) # make sure it's still in the model self.assertIn(tmp_metabolite, model.metabolites) self.assertEqual(len(tmp_metabolite.reactions), 0) self.assertEqual(len(self.model.reactions), old_reaction_count - 1) # Now try it with removing orphans model.reactions[0].add_metabolites({tmp_metabolite: 1}) self.assertEqual(len(tmp_metabolite.reactions), 1) model.reactions[0].delete(remove_orphans=True) self.assertNotIn(tmp_metabolite, model.metabolites) self.assertEqual(len(tmp_metabolite.reactions), 0) self.assertEqual(len(self.model.reactions), old_reaction_count - 2) # It shouldn't remove orphans if it's in 2 reactions however model.reactions[0].add_metabolites({tmp_metabolite: 1}) model.reactions[1].add_metabolites({tmp_metabolite: 1}) self.assertEqual(len(tmp_metabolite.reactions), 2) model.reactions[0].delete(remove_orphans=False) self.assertIn(tmp_metabolite, model.metabolites) self.assertEqual(len(tmp_metabolite.reactions), 1) self.assertEqual(len(self.model.reactions), old_reaction_count - 3)
def parse_coeff_and_metabolites(term): try: coeff, metabolite_id = term.strip().split(' ') except: raise ValueError( 'Something is fishy with the provided term %s' % term) return Metabolite(metabolite_id), factor * float(coeff)
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 get_emu_metabolite(emu_dict, label_model): """ Creates a cobra metabolite object for the new emu. Additionally it will add additional information if the emu is symmetryc label_model: label_model object emu_dict: dict dict that contains the ID of the metabolite (or group of metabolites) and the carbon range """ #print emu_dict met_id = emu_dict["met_id"] carbons = emu_dict["carbons"] iso_object = label_model.id_isotopomer_object_dict[met_id] emuid = "emu_" + met_id + "_" carbon_range_string = "" for carbon in carbons: carbon_range_string += str(carbon) if iso_object.symm == True: #build a symetryc dic symm_dict = {} forward_range = range(1, iso_object.n + 1) reverse_range = range(iso_object.n, 0, -1) for x in forward_range: symm_dict[x] = reverse_range[x - 1] #print symm_dict symm_carbons = [] for carbon in carbons: symm_carbons.append(symm_dict[carbon]) #print symm_carbons symm_carbons = sorted(symm_carbons) emu_dict["symm_carbons"] = symm_carbons if symm_carbons != carbons: #Check if they are not equal: #Identfy the lower range, which will be written first in the metabolite id symm_carbon_range_string = "" for carbon in symm_carbons: symm_carbon_range_string += str(carbon) if symm_carbons[0] < carbons[0]: emuid += symm_carbon_range_string + "_and_" + carbon_range_string else: emuid += carbon_range_string + "_and_" + symm_carbon_range_string else: emu_dict["symm_carbons"] = [] emuid += carbon_range_string else: emuid += carbon_range_string if emuid in label_model.emu_model.metabolites: emu_met = label_model.emu_model.metabolites.get_by_id(emuid) present_flag = True else: comp = label_model.simplified_metabolic_model.metabolites.get_by_id( emu_dict["met_id"]).compartment emu_met = Metabolite(emuid, formula='', name=emuid, compartment=comp) present_flag = False met_id = emu_dict["met_id"] label_model.emu_metabolite_dict[emu_met] = met_id if met_id not in label_model.metabolite_emu_dict: label_model.metabolite_emu_dict[met_id] = [] label_model.metabolite_emu_dict[met_id].append(emu_met.id) return (emu_met, emu_dict, present_flag)
def define_reaction_group(model, reaction_dict, group_reaction_id=None, lower_bound=None, upper_bound=None, objective_coefficient=0): new_reaction_id = "RGROUP" if group_reaction_id != None: if "RGROUP" in group_reaction_id: new_reaction_id = group_reaction_id else: new_reaction_id += "_" + group_reaction_id else: for reaction_id in reaction_dict: new_reaction_id += "_" + reaction_id if new_reaction_id in model.reactions: model.reactions.get_by_id(new_reaction_id).remove_from_model() new_reaction_name = "Reaction Group:" for reaction_id in reaction_dict: if reaction_dict[reaction_id] > 0: new_reaction_name += "+" + reaction_id else: new_reaction_name += "-" + reaction_id metabolite = Metabolite("m" + new_reaction_id, formula='', name="mGROUP" + new_reaction_id, compartment='gr') group_reaction = Reaction(new_reaction_id) group_reaction.name = new_reaction_name group_reaction.subsystem = 'Reaction group' if upper_bound != None: group_reaction.upper_bound = upper_bound group_reaction.add_metabolites({metabolite: -1}) if objective_coefficient == None: group_reaction.objective_coefficient = 0 model.add_reaction(group_reaction) group_reaction.objective_coefficient = objective_coefficient theoretical_lower_bound = 0 theoretical_upper_bound = 0 for reaction_id in reaction_dict: coef = reaction_dict[reaction_id] reaction = model.reactions.get_by_id(reaction_id) reaction.add_metabolites({metabolite: coef}) if coef >= 0: theoretical_upper_bound += reaction.upper_bound theoretical_lower_bound += reaction.lower_bound else: theoretical_upper_bound -= reaction.lower_bound theoretical_lower_bound -= reaction.upper_bound if lower_bound == None: group_reaction.lower_bound = min( round_down(theoretical_lower_bound, 2), 0) else: group_reaction.lower_bound = lower_bound if upper_bound == None: group_reaction.upper_bound = max(round_up(theoretical_upper_bound, 2), 1000) else: group_reaction.upper_bound = upper_bound
def test_impossible_req(self): model = self.model.copy() D = Metabolite("D") model.add_metabolites([D]) opt = CORDA(model, self.conf, met_prod=["D"]) need = opt.associated(["EX_CORDA_0"]) self.assertTrue(len(need["EX_CORDA_0"]) == 0) self.assertTrue("EX_CORDA_0" in opt.impossible)
def add_met(model, met_id, name, formula, compartment): '''Add metabolite.''' met = Metabolite(met_id, formula=formula, name=name, compartment=compartment) return model.add_metabolites([met])
def test_inequality(self): # The space enclosed by the constraints is a 2D triangle with # vertexes as (3, 0), (1, 2), and (0, 1) solver = self.solver # c1 encodes y - x > 1 ==> y > x - 1 # c2 encodes y + x < 3 ==> y < 3 - x c1 = Metabolite("c1") c2 = Metabolite("c2") x = Reaction("x") x.lower_bound = 0 y = Reaction("y") y.lower_bound = 0 x.add_metabolites({c1: -1, c2: 1}) y.add_metabolites({c1: 1, c2: 1}) c1._bound = 1 c1._constraint_sense = "G" c2._bound = 3 c2._constraint_sense = "L" m = Model() m.add_reactions([x, y]) # test that optimal values are at the vertices m.change_objective("x") self.assertAlmostEqual(solver.solve(m).f, 1.0) self.assertAlmostEqual(solver.solve(m).x_dict["y"], 2.0) m.change_objective("y") self.assertAlmostEqual(solver.solve(m).f, 3.0) self.assertAlmostEqual(solver.solve(m, objective_sense="minimize").f, 1.0)
def test_solve_mip(self): solver = self.solver cobra_model = Model('MILP_implementation_test') constraint = Metabolite("constraint") constraint._bound = 2.5 x = Reaction("x") x.lower_bound = 0. x.objective_coefficient = 1. x.add_metabolites({constraint: 2.5}) y = Reaction("y") y.lower_bound = 0. y.objective_coefficient = 1. y.add_metabolites({constraint: 1.}) cobra_model.add_reactions([x, y]) float_sol = solver.solve(cobra_model) # add an integer constraint y.variable_kind = "integer" int_sol = solver.solve(cobra_model) self.assertAlmostEqual(float_sol.f, 2.5) self.assertAlmostEqual(float_sol.x_dict["y"], 2.5) self.assertAlmostEqual(int_sol.f, 2.2) self.assertAlmostEqual(int_sol.x_dict["y"], 2.0)
def convert_to_irreversible_with_indicators(cobra_model,reaction_id_list=[],metabolite_list=[], mutually_exclusive_directionality_constraint = False,label_model=None): #Function modified from the work by : """Schmidt BJ1, Ebrahim A, Metz TO, Adkins JN, Palsson B, Hyduke DR. GIM3E: condition-specific models of cellular metabolism developed from metabolomics and expression data Bioinformatics. 2013 Nov 15;29(22):2900-8. doi: 10.1093/bioinformatics/btt493. Epub 2013 Aug 23.""" """Will break all of the reversible reactions into two separate irreversible reactions with different directions. This function call modified from a version in the core cobra to facilitate the MILP formulation and include gene_reaction_rules with the reverse reaction Arguments: cobra_model: A model object which will be modified in place. mutually_exclusive_directionality_constraint: Boolean. If True, turnover reactions are constructed to serve as MILP constraints to prevent loops. Returns: None, cobra_model is modified in place """ reactions_to_add = [] reactions_to_make_irreversible=[] if reaction_id_list==[] or reaction_id_list==None: reaction_id_list=[x.id for x in cobra_model.reactions] for x in reaction_id_list: reactions_to_make_irreversible.append(cobra_model.reactions.get_by_id(x)) """for x in lexs: reactions_to_make_irreversible.append(cobra_model.reactions.get_by_id(x))""" #If a label model object is provided make sure all experimentally measured metabolites (or at least one of the metabolites in the pool) is produced full_metabolite_list=copy.copy(metabolite_list) print full_metabolite_list if label_model!=None: emus=[] for condition in label_model.experimental_dict: for emu in label_model.experimental_dict[condition]: if emu not in emus: emus.append(emu) measured_metabolite_dict={} for emu in emus: iso_id=str(label_model.emu_dict[emu]["met_id"]) #print label_model.id_isotopomer_object_dict #isotopomer_object=label_model.id_isotopomer_object_dict[iso_id] metabolites=label_model.isotopomer_id_metabolite_id_dict[iso_id] print [iso_id,label_model.isotopomer_id_metabolite_id_dict[iso_id]] if isinstance(metabolites,list): for metabolite in metabolites: full_metabolite_list.append(metabolite) else: full_metabolite_list.append(metabolites) for metabolites in full_metabolite_list: print metabolites if not isinstance(metabolites,list): metabolites=[metabolites] for metabolite in metabolites: print metabolite the_metabolite=cobra_model.metabolites.get_by_id(metabolite) for x in the_metabolite.reactions: if x not in reactions_to_make_irreversible: reactions_to_make_irreversible.append(x) for reaction in reactions_to_make_irreversible: # Potential artifact because a reaction might run backwards naturally # and this would result in adding an empty reaction to the # model in addition to the reverse reaction. if reaction.lower_bound < 0: #reverse_reaction = Reaction(reaction.id + "_reverse") reverse_reaction = reaction.copy() reverse_reaction.id = reaction.id + "_reverse" reverse_reaction.lower_bound = max(0,-1*reaction.upper_bound) reverse_reaction.upper_bound = reaction.lower_bound * -1. reaction.lower_bound = 0 if reaction.upper_bound<0: reaction.upper_bound=0 # Make the directions aware of each other reaction.notes["reflection"] = reverse_reaction.id reverse_reaction.notes["reflection"] = reaction.id reaction_dict = {} current_metabolites = [x for x in reaction.metabolites] for the_metabolite in current_metabolites: reaction_dict[the_metabolite] = -2 * reaction.get_coefficient(the_metabolite.id) reverse_reaction.add_metabolites(reaction_dict) reactions_to_add.append(reverse_reaction) # Also: GPRs should already copy # reverse_reaction.gene_reaction_rule = reaction.gene_reaction_rule # reverse_reaction._genes = reaction._genes if mutually_exclusive_directionality_constraint: # A continuous reaction bounded by 0., 1. # Serves as a source for the indicator metabolites tmp_source = Reaction('IRRMILP_direction_constraint_source_for_%s_and_%s' %(reaction.id, reverse_reaction.id)) tmp_source.upper_bound = 1. tmp_source.lower_bound = 0. # The reverse indicator reaction is # an integer-valued reaction bounded by 0,1 # that activates flux to the reverse reaction # and deactivates the forward reaction only when it is # turned on to 1 tmp_indicator = Reaction('IRRMILP_reverse_indicator_for_%s_and_%s' %(reaction.id, reverse_reaction.id)) tmp_indicator.upper_bound = 1 tmp_indicator.lower_bound = 0 tmp_indicator.variable_kind = 'integer' flux_constraint_forward = Metabolite(id = 'IRRMILP_direction_constraint_for_%s'%reaction.id) flux_constraint_reverse = Metabolite(id = 'IRRMILP_direction_constraint_for_%s'%reverse_reaction.id) flux_constraint_reverse._constraint_sense = 'G' flux_constraint_reverse._bound = 0. tmp_source.add_metabolites({flux_constraint_forward: 1}) tmp_indicator.add_metabolites({flux_constraint_forward: -1, flux_constraint_reverse: 1}) if reaction.upper_bound != 0: reaction.add_metabolites({flux_constraint_forward: -1./reaction.upper_bound}) else: # could put 1.01 X the tolerance here, # This is arbitrary. Use 0.001 # since 1000 is a typical upper bound reaction.add_metabolites({flux_constraint_forward: -0.001}) if reverse_reaction.upper_bound != 0: reverse_reaction.add_metabolites({flux_constraint_reverse: -1./reverse_reaction.upper_bound}) else: reverse_reaction.add_metabolites({flux_constraint_reverse: -0.001}) reactions_to_add.append(tmp_indicator) reactions_to_add.append(tmp_source) cobra_model.add_reactions(reactions_to_add)
def __init__(self, id): Component.__init__(self, id) pass
def test_metabolite_formula(self): met = Metabolite("water") met.formula = "H2O" self.assertEqual(met.elements, {"H": 2, "O": 1}) self.assertEqual(met.formula_weight, 18.01528)
temp_metabolite_dict = {popsicle_consumed: -1} Popsicle_consumed_sink.add_metabolites(temp_metabolite_dict) the_reactions.append(Popsicle_consumed_sink) ## add all reactions cobra_model.add_reactions(the_reactions) # set objective coefficients Cone_consumption.objective_coefficient = cone_selling_price Popsicle_consumption.objective_coefficient = popsicle_selling_price Cone_production.objective_coefficient = -1*cone_production_cost Popsicle_production.objective_coefficient = -1*popsicle_production_cost production_capacity_constraint = Metabolite(id='production_capacity_constraint') production_capacity_constraint._constraint_sense = 'L' production_capacity_constraint._bound = starting_budget; Cone_production.add_metabolites({production_capacity_constraint: cone_production_cost }) Popsicle_production.add_metabolites({production_capacity_constraint: popsicle_production_cost }) print() print('Here is what happens in the continuous (LP) case...') the_program = cobra_model.optimize(objective_sense='maximize') print() print(('Status is: %s'%cobra_model.solution.status)) print(('Objective value is: %1.2f'%cobra_model.solution.f)) for the_reaction, the_value in cobra_model.solution.x_dict.items():
def convertMPStoCobraModel(filename, verbose = False,defaultbound = 1000, objective = 'Growth'): keywords = ['NAME','ROWS','COLUMNS','RHS','RANGES','BOUNDS','ENDATA'] with open(filename, 'r') as sourcefile: ##Syntax: MPStoCobraModel.py filename_in filename_out metabolite_list = [] for line in sourcefile: if "*" in line: continue #Ignore commmented lines linestart = line.split(' ')[0].split('\n')[0] if linestart in keywords: if verbose: print 'keyword found:',linestart lastkeyword = linestart if (lastkeyword == 'NAME'): modelname = line.split(' ')[-1] cobramodel = cobra.Model(modelname) cobramodel.id = modelname cobramodel.description = modelname #Add metabolites to model: if lastkeyword == 'ROWS' and (linestart not in keywords): metabolite_id = line.strip().rsplit(' ',1)[1] row_type = line.strip().rsplit(' ',1)[0].strip() metabolite_list.append(metabolite_id) new_metabolite = Metabolite(metabolite_id) if new_metabolite.id.endswith('xt'): new_metabolite.compartment = 'e' else: new_metabolite.compartment = 'c' if row_type == 'E': cobramodel.add_metabolites([new_metabolite]) if verbose: print 'metabolite added:',new_metabolite #Construct reactions: if lastkeyword == 'COLUMNS' and (linestart not in keywords): rdata = line.strip().split() reaction_id = rdata[0] metabolite_id = rdata[1] coef = float(rdata[2]) if metabolite_id == 'COST': continue #Ignore the "COST" metabolite if metabolite_id not in cobramodel.metabolites: print 'metabolite_id:',metabolite_id raise Exception ('Metabolite not found.') else: current_metabolite = cobramodel.metabolites.get_by_id(metabolite_id) if reaction_id not in cobramodel.reactions: current_reaction = Reaction(reaction_id) current_reaction.add_metabolites({current_metabolite:coef}) cobramodel.add_reactions(current_reaction) else: current_reaction = cobramodel.reactions.get_by_id(reaction_id) current_reaction.add_metabolites({current_metabolite:coef}) if lastkeyword == 'BOUNDS' and (linestart not in keywords): data = line.strip().split() bound_type = data[0] reaction_id = data[2] if len(data) > 3: bound_value = float(data[3]) if bound_type == 'FR': cobramodel.reactions.get_by_id(reaction_id).lower_bound = -defaultbound cobramodel.reactions.get_by_id(reaction_id).upper_bound = defaultbound elif bound_type == 'LO': cobramodel.reactions.get_by_id(reaction_id).lower_bound = bound_value elif bound_type == 'UP': cobramodel.reactions.get_by_id(reaction_id).upper_bound = bound_value elif bound_type == 'FX': try: cobramodel.reactions.get_by_id(reaction_id).lower_bound = bound_value except KeyError: print cobramodel.reactions cobramodel.reactions.get_by_id(reaction_id).upper_bound = bound_value #print bound_type,reaction_id,bound_values #Rename external metabolites for metabolite in cobramodel.metabolites: if metabolite.id.endswith('xt'): if verbose: print 'renaming metabolite ',metabolite.id new_metabolite_id = metabolite.id.split('xt')[0] + '_e' metabolite.id = new_metabolite_id if verbose: print 'new metabolite id:',metabolite.id #Combine in/out exchange reactions: for reaction in cobramodel.reactions: if reaction.id.endswith('xtO'): #If the reaction is an "out" exchange reaction metabolite_id = reaction.id.split('xtO')[0] in_reaction_id = metabolite_id + 'xtI' #Construct the ID of the corresponding "in" reaction if in_reaction_id in cobramodel.reactions: #If a corresponding "in" reaction exists: bound_in = cobramodel.reactions.get_by_id(in_reaction_id).upper_bound #Find the maximal uptake rate defined by the "in" reaction upper bounds reaction.lower_bound = -bound_in #Make the reaction a combined in/out exchange reaction by allowing negative flow (if allowed by the "in" reaction) cobramodel.reactions.get_by_id(in_reaction_id).remove_from_model() #Remove redundant "in" reactions reaction.id = 'EX_' + metabolite_id #Rename the now combined exchange reaction if objective is not None and (objective in cobramodel.reactions): cobramodel.reactions.get_by_id(objective).objective_coefficient = 1 return cobramodel
# In this case, the quadratic objective is simply the identity matrix Q.todense() # Output: # matrix([[ 1., 0.], # [ 0., 1.]]) # We need to use a solver that supports quadratic programming, such as gurobi # or cplex. If a solver which supports quadratic programming is installed, this # function will return its name. print(solvers.get_solver_name(qp=True)) # Prints: # gurobi c = Metabolite("c") c._bound = 2 x = Reaction("x") y = Reaction("y") x.add_metabolites({c: 1}) y.add_metabolites({c: 1}) m = Model() m.add_reactions([x, y]) sol = m.optimize(quadratic_component=Q, objective_sense="minimize") sol.x_dict # Output: # {'x': 1.0, 'y': 1.0} # Suppose we change the problem to have a mixed linear and quadratic objective. # # > **min** $\frac{1}{2}\left(x^2 + y^2 \right) - y$
def create_modelFromReactionsAndMetabolitesTables(self,rxns_table_I,mets_table_I): '''generate a cobra model from isotopomer_modelReactions and isotopomer_modelMetabolites tables''' cobra_model = Model(rxns_table_I[0]['model_id']); for rxn_cnt,rxn_row in enumerate(rxns_table_I): #if rxn_row['rxn_id'] == 'HEX1': # print 'check' mets = {} print(rxn_row['rxn_id']) # parse the reactants for rxn_met_cnt,rxn_met in enumerate(rxn_row['reactants_ids']): for met_cnt,met_row in enumerate(mets_table_I): if met_row['met_id']==rxn_met:# and met_row['balanced']: compartment = met_row['compartment'] if not compartment: met_id_tmp = met_row['met_id'].split('.')[0] compartment = met_id_tmp.split('_')[-1]; met_tmp = Metabolite(met_row['met_id'],met_row['formula'],met_row['met_name'],compartment) met_tmp.charge = met_row['charge'] # check for duplicate metabolites met_keys = list(mets.keys()); met_keys_ids = {}; if met_keys: for cnt,met in enumerate(met_keys): met_keys_ids[met.id]=cnt; if met_tmp.id in list(met_keys_ids.keys()): mets[met_keys[met_keys_ids[met_tmp.id]]]-=1 else: mets[met_tmp] = rxn_row['reactants_stoichiometry'][rxn_met_cnt]; break; # parse the products for rxn_met_cnt,rxn_met in enumerate(rxn_row['products_ids']): for met_cnt,met_row in enumerate(mets_table_I): if met_row['met_id']==rxn_met:# and met_row['balanced']: compartment = met_row['compartment'] if not compartment: met_id_tmp = met_row['met_id'].split('.')[0] compartment = met_id_tmp.split('_')[-1]; met_tmp = Metabolite(met_row['met_id'],met_row['formula'],met_row['met_name'],compartment) met_tmp.charge = met_row['charge'] # check for duplicate metabolites met_keys = list(mets.keys()); met_keys_ids = {}; if met_keys: for cnt,met in enumerate(met_keys): met_keys_ids[met.id]=cnt; if met_tmp.id in list(met_keys_ids.keys()): mets[met_keys[met_keys_ids[met_tmp.id]]]+=1 else: mets[met_tmp] = rxn_row['products_stoichiometry'][rxn_met_cnt]; break; rxn = None; rxn = Reaction(rxn_row['rxn_id']); rxn.add_metabolites(mets); rxn.lower_bound=rxn_row['lower_bound']; rxn.upper_bound=rxn_row['upper_bound']; rxn.subsystem=rxn_row['subsystem']; rxn.gpr=rxn_row['gpr']; rxn.objective_coefficient=rxn_row['objective_coefficient']; cobra_model.add_reactions([rxn]); cobra_model.repair(); return cobra_model
cone_selling_price = 7. cone_production_cost = 3. popsicle_selling_price = 2. popsicle_production_cost = 1. starting_budget = 100. # This problem can be written as a cobra.Model from cobra import Model, Metabolite, Reaction cone = Reaction("cone") popsicle = Reaction("popsicle") # constrainted to a budget budget = Metabolite("budget") budget._constraint_sense = "L" budget._bound = starting_budget cone.add_metabolites({budget: cone_production_cost}) popsicle.add_metabolites({budget: popsicle_production_cost}) # objective coefficient is the profit to be made from each unit cone.objective_coefficient = cone_selling_price - cone_production_cost popsicle.objective_coefficient = popsicle_selling_price - \ popsicle_production_cost m = Model("lerman_ice_cream_co") m.add_reactions((cone, popsicle)) m.optimize().x_dict # Output:
def solve_mip(self): cone_selling_price = 7.0 cone_production_cost = 3.0 popsicle_selling_price = 2.0 popsicle_production_cost = 1.0 starting_budget = 100.0 cobra_model = Model("MILP_implementation_test") cone_out = Metabolite(id="cone_out", compartment="c") cone_in = Metabolite(id="cone_in", compartment="c") cone_consumed = Metabolite(id="cone_consumed", compartment="c") popsicle_out = Metabolite(id="popsicle_out", compartment="c") popsicle_in = Metabolite(id="popsicle_in", compartment="c") popsicle_consumed = Metabolite(id="popsicle_consumed", compartment="c") the_reactions = [] # SOURCE Cone_source = Reaction(name="Cone_source") temp_metabolite_dict = {cone_out: 1} Cone_source.add_metabolites(temp_metabolite_dict) the_reactions.append(Cone_source) Popsicle_source = Reaction(name="Popsicle_source") temp_metabolite_dict = {popsicle_out: 1} Popsicle_source.add_metabolites(temp_metabolite_dict) the_reactions.append(Popsicle_source) ## PRODUCTION Cone_production = Reaction(name="Cone_production") temp_metabolite_dict = {cone_out: -1, cone_in: 1} Cone_production.add_metabolites(temp_metabolite_dict) the_reactions.append(Cone_production) Popsicle_production = Reaction(name="Popsicle_production") temp_metabolite_dict = {popsicle_out: -1, popsicle_in: 1} Popsicle_production.add_metabolites(temp_metabolite_dict) the_reactions.append(Popsicle_production) ## CONSUMPTION Cone_consumption = Reaction(name="Cone_consumption") temp_metabolite_dict = {cone_in: -1, cone_consumed: 1} Cone_consumption.add_metabolites(temp_metabolite_dict) the_reactions.append(Cone_consumption) Popsicle_consumption = Reaction(name="Popsicle_consumption") temp_metabolite_dict = {popsicle_in: -1, popsicle_consumed: 1} Popsicle_consumption.add_metabolites(temp_metabolite_dict) the_reactions.append(Popsicle_consumption) # SINK Cone_consumed_sink = Reaction(name="Cone_consumed_sink") temp_metabolite_dict = {cone_consumed: -1} Cone_consumed_sink.add_metabolites(temp_metabolite_dict) the_reactions.append(Cone_consumed_sink) Popsicle_consumed_sink = Reaction(name="Popsicle_consumed_sink") temp_metabolite_dict = {popsicle_consumed: -1} Popsicle_consumed_sink.add_metabolites(temp_metabolite_dict) the_reactions.append(Popsicle_consumed_sink) ## add all reactions cobra_model.add_reactions(the_reactions) # set objective coefficients Cone_consumption.objective_coefficient = cone_selling_price Popsicle_consumption.objective_coefficient = popsicle_selling_price Cone_production.objective_coefficient = -1 * cone_production_cost Popsicle_production.objective_coefficient = -1 * popsicle_production_cost # Make sure we produce whole cones Cone_production.variable_kind = "integer" Popsicle_production.variable_kind = "integer" production_capacity_constraint = Metabolite(id="production_capacity_constraint") production_capacity_constraint._constraint_sense = "L" production_capacity_constraint._bound = starting_budget Cone_production.add_metabolites({production_capacity_constraint: cone_production_cost}) Popsicle_production.add_metabolites({production_capacity_constraint: popsicle_production_cost}) cobra_model.optimize(solver=solver_name) self.assertEqual(133, cobra_model.solution.f) self.assertEqual(33, cobra_model.solution.x_dict["Cone_consumption"])