def _add_target_constraints(self, c): """Add the target constraints to the dual model""" targets = self._target_constraints w_reactions = [] for i, target in enumerate(targets): assert isinstance(target, optlang.interface.Constraint) if not target.is_Linear: raise ValueError("Target constraints must be linear.") if (target.lb is None and target.ub is None) or (target.lb is not None and target.ub is not None): raise ValueError("Target constraints must be one-sided inequalities.") coefficients_dict = target.expression.as_coefficients_dict() w_reac = Reaction("w_" + str(i)) w_reac.lower_bound = c if target.ub is not None: coefficients = { self._dual_model.metabolites.get_by_id(var.name): coef for var, coef in coefficients_dict.items() if var.name in self._dual_model.metabolites } elif target.lb is not None: coefficients = { self._dual_model.metabolites.get_by_id(var.name): -coef for var, coef in coefficients_dict.items() if var.name in self._dual_model.metabolites } w_reac.add_metabolites(coefficients) w_reactions.append(w_reac) self._dual_model.add_reactions(w_reactions) return None
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 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 create_adapter_reactions(original_metabolites, database, mapping, compartment_regexp): adapter_reactions = [] for metabolite in original_metabolites: # model is the original host model if not compartment_regexp.match(metabolite.id): continue name = metabolite.id[0:-2] try: mapped_name = mapping[name] except KeyError: continue # print name, 'N/A' adapter_reaction = Reaction('adapter_' + metabolite.id + '_' + mapped_name) adapter_reaction.lower_bound = -1000 try: adapter_reaction.add_metabolites({ metabolite: -1, database.metabolites.get_by_id(mapped_name): 1 }) except KeyError: pass else: adapter_reactions.append(adapter_reaction) return adapter_reactions
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 _add_target_constraints(self, c): """Add the target constraints to the dual model""" targets = self._target_constraints w_reactions = [] for i, target in enumerate(targets): assert isinstance(target, optlang.interface.Constraint) if not target.is_Linear: raise ValueError("Target constraints must be linear.") if (target.lb is None and target.ub is None) or (target.lb is not None and target.ub is not None): raise ValueError( "Target constraints must be one-sided inequalities.") coefficients_dict = target.expression.as_coefficients_dict() w_reac = Reaction("w_" + str(i)) w_reac.lower_bound = c if target.ub is not None: coefficients = { self._dual_model.metabolites.get_by_id(var.name): coef for var, coef in coefficients_dict.items() if var.name in self._dual_model.metabolites } elif target.lb is not None: coefficients = { self._dual_model.metabolites.get_by_id(var.name): -coef for var, coef in coefficients_dict.items() if var.name in self._dual_model.metabolites } w_reac.add_metabolites(coefficients) w_reactions.append(w_reac) self._dual_model.add_reactions(w_reactions) return None
def construct_universal_model(list_of_db_prefixes): # Select which reactions to include in universal reaction database reaction_selection = reac_prop[[ any([source.startswith(db_prefix) for db_prefix in list_of_db_prefixes]) and re.match('.*biomass.*', source, re.I) is None for source in reac_prop.Source]] reactions = list() for index, row in reaction_selection.iterrows(): try: stoichiometry = parse_reaction(row.Equation, rev_arrow='=') except ValueError: continue else: for met, coeff in stoichiometry.items(): met.name = chem_prop.loc[met.id]['name'] try: met.formula = Formula(chem_prop.loc[met.id].formula) except: logger.debug('Cannot parse formula %s. Skipping formula' % chem_prop.loc[met.id].formula) continue # if met.formula.weight is None: # logger.debug('Cannot calculate weight for formula %s. Skipping reaction %s' % (met.formula, row.Equation)) # # print('Cannot calculate weight for formula %s. Skipping reaction %s' % (met.formula, row.Equation)) # continue try: met.charge = int(chem_prop.loc[met.id].charge) except (ValueError, TypeError): logger.debug('Cannot parse charge %s. Skipping charge' % chem_prop.loc[met.id].charge) pass rest = chem_prop.loc[met.id].to_dict() met.annotation = dict((key, rest[key]) for key in rest if key in ('mass', 'InChI', 'source')) mets = [met.id for met in stoichiometry.keys()] if len(mets) != len(set(mets)): continue reaction = Reaction(index) reaction.add_metabolites(stoichiometry) try: if len(reaction.check_mass_balance()) != 0: continue except AttributeError as e: logger.debug(str(e)) continue if row.Balance: reaction.lower_bound = -1 * reaction.upper_bound reaction.name = row['Source'] row = row.fillna("") rest = row.to_dict() reaction.annotation = dict((key, rest[key]) for key in rest if key in ('EC', 'Description')) reactions.append(reaction) model = Model('metanetx_universal_model_' + '_'.join(list_of_db_prefixes), solver_interface=optlang.interface) model.add_reactions(reactions) # Add sinks for all metabolites for metabolite in model.metabolites: model.add_demand(metabolite) return model
def construct_universal_model(list_of_db_prefixes): # Select which reactions to include in universal reaction database reaction_selection = reac_prop[[ any([source.startswith(db_prefix) for db_prefix in list_of_db_prefixes]) and re.match('.*biomass.*', source, re.I) is None for source in reac_prop.Source]] reactions = list() for index, row in reaction_selection.iterrows(): try: stoichiometry = parse_reaction(row.Equation, rev_arrow='=') except ValueError: continue else: for met, coeff in stoichiometry.iteritems(): met.name = chem_prop.loc[met.id]['name'] try: met.formula = Formula(chem_prop.loc[met.id].formula) except: logger.debug('Cannot parse formula %s. Skipping formula' % chem_prop.loc[met.id].formula) continue # if met.formula.weight is None: # logger.debug('Cannot calculate weight for formula %s. Skipping reaction %s' % (met.formula, row.Equation)) # # print('Cannot calculate weight for formula %s. Skipping reaction %s' % (met.formula, row.Equation)) # continue try: met.charge = int(chem_prop.loc[met.id].charge) except (ValueError, TypeError): logger.debug('Cannot parse charge %s. Skipping charge' % chem_prop.loc[met.id].charge) pass rest = chem_prop.loc[met.id].to_dict() met.annotation = dict((key, rest[key]) for key in rest if key in ('mass', 'InChI', 'source')) mets = [met.id for met in stoichiometry.keys()] if len(mets) != len(set(mets)): continue reaction = Reaction(index) reaction.add_metabolites(stoichiometry) if reaction.check_mass_balance() != []: continue if row.Balance: reaction.lower_bound = -1 * reaction.upper_bound reaction.name = row['Source'] rest = row.to_dict() reaction.annotation = dict((key, rest[key]) for key in rest if key in ('EC', 'Description')) reactions.append(reaction) model = Model('metanetx_universal_model_' + '_'.join(list_of_db_prefixes), solver_interface=optlang.interface) model.add_reactions(reactions) # Add sinks for all metabolites for metabolite in model.metabolites: model.add_demand(metabolite) return model
def test_reaction_knock_in_target(self): reaction = Reaction(id="atpzase", name="Cosmic ATP generator") atp_z = Metabolite(id="atp_z", name="Cosmic ATP", compartment="c") reaction.add_metabolites({self.model.metabolites.atp_c: 1, atp_z: -1}) knockin_target = ReactionKnockinTarget("atpzase", reaction) with TimeMachine() as tm: knockin_target.apply(self.model, time_machine=tm) self.assertIn(atp_z, self.model.metabolites) self.assertIn(reaction, self.model.reactions) self.assertNotIn(atp_z, self.model.metabolites) self.assertNotIn(reaction, self.model.reactions)
def test_reaction_knock_in_target(self, model): reaction = Reaction(id="atpzase", name="Cosmic ATP generator") atp_z = Metabolite(id="atp_z", name="Cosmic ATP", compartment="c") reaction.add_metabolites({model.metabolites.atp_c: 1, atp_z: -1}) knockin_target = ReactionKnockinTarget("atpzase", reaction) with TimeMachine() as tm: knockin_target.apply(model, time_machine=tm) assert atp_z in model.metabolites assert reaction in model.reactions assert atp_z not in model.metabolites assert reaction not in model.reactions
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_make_lhs_irreversible_reversible(self): model = self.model rxn = Reaction('test') rxn.add_metabolites({model.metabolites[0]: -1., model.metabolites[1]: 1.}) rxn.lower_bound = -999999. rxn.upper_bound = -100 model.add_reaction(rxn) self.assertEqual(rxn.lower_bound, -999999.) self.assertEqual(rxn.upper_bound, -100.) self.assertEqual(rxn.forward_variable.lb, 0.) self.assertEqual(rxn.forward_variable.ub, 0.) self.assertEqual(rxn.reverse_variable.lb, 100.) self.assertEqual(rxn.reverse_variable.ub, 999999.) rxn.upper_bound = 666. self.assertEqual(rxn.lower_bound, -999999.) self.assertEqual(rxn.upper_bound, 666.) self.assertEqual(rxn.forward_variable.lb, 0.) self.assertEqual(rxn.forward_variable.ub, 666) self.assertEqual(rxn.reverse_variable.lb, 0.) self.assertEqual(rxn.reverse_variable.ub, 999999.)
def create_adapter_reactions(original_metabolites, database, mapping, compartment_regexp): adapter_reactions = [] for metabolite in original_metabolites: # model is the original host model if not compartment_regexp.match(metabolite.id): continue name = metabolite.id[0:-2] try: mapped_name = mapping[name] except KeyError: continue # print name, 'N/A' adapter_reaction = Reaction('adapter_' + metabolite.id + '_' + mapped_name) adapter_reaction.lower_bound = -1000 try: adapter_reaction.add_metabolites({metabolite: -1, database.metabolites.get_by_id(mapped_name): 1}) except KeyError: pass else: adapter_reactions.append(adapter_reaction) return adapter_reactions
def test_make_lhs_irreversible_reversible(self): model = self.model rxn = Reaction('test') rxn.add_metabolites({ model.metabolites[0]: -1., model.metabolites[1]: 1. }) rxn.lower_bound = -999999. rxn.upper_bound = -100 model.add_reaction(rxn) self.assertEqual(rxn.lower_bound, -999999.) self.assertEqual(rxn.upper_bound, -100.) self.assertEqual(rxn.forward_variable.lb, 0.) self.assertEqual(rxn.forward_variable.ub, 0.) self.assertEqual(rxn.reverse_variable.lb, 100.) self.assertEqual(rxn.reverse_variable.ub, 999999.) rxn.upper_bound = 666. self.assertEqual(rxn.lower_bound, -999999.) self.assertEqual(rxn.upper_bound, 666.) self.assertEqual(rxn.forward_variable.lb, 0.) self.assertEqual(rxn.forward_variable.ub, 666) self.assertEqual(rxn.reverse_variable.lb, 0.) self.assertEqual(rxn.reverse_variable.ub, 999999.)
def test_gnomic_integration(self): from gnomic.models import Accession, Feature, Mutation, FeatureTree abstract_target = Target("test") abstract_target_gnomic = abstract_target.to_gnomic() self.assertIsInstance(abstract_target_gnomic, Accession) self.assertEqual(abstract_target_gnomic.identifier, abstract_target.id) flux_modulation_target = FluxModulationTarget("test", 1, 0) flux_modulation_target_gnomic = flux_modulation_target.to_gnomic() self.assertIsInstance(flux_modulation_target_gnomic, Mutation) self.assertIsInstance(flux_modulation_target_gnomic.old, FeatureTree) self.assertIsInstance(flux_modulation_target_gnomic.old[0], Feature) self.assertEqual( flux_modulation_target_gnomic.old[0].accession.identifier, flux_modulation_target.id) self.assertEqual(flux_modulation_target_gnomic.old[0].variant, None) self.assertEqual(flux_modulation_target_gnomic.old[0].type, 'flux') self.assertIsInstance(flux_modulation_target_gnomic.new, FeatureTree) self.assertIsInstance(flux_modulation_target_gnomic.new[0], Feature) self.assertEqual( flux_modulation_target_gnomic.new[0].accession.identifier, flux_modulation_target.id) self.assertEqual(flux_modulation_target_gnomic.new[0].type, 'flux') self.assertEqual( flux_modulation_target_gnomic.new[0].variant, "over-expression(%f)" % flux_modulation_target.fold_change) flux_modulation_target = FluxModulationTarget("test", 0.5, 1) flux_modulation_target_gnomic = flux_modulation_target.to_gnomic() self.assertIsInstance(flux_modulation_target_gnomic, Mutation) self.assertIsInstance(flux_modulation_target_gnomic.old, FeatureTree) self.assertIsInstance(flux_modulation_target_gnomic.old[0], Feature) self.assertEqual( flux_modulation_target_gnomic.old[0].accession.identifier, flux_modulation_target.id) self.assertEqual(flux_modulation_target_gnomic.old[0].variant, None) self.assertEqual(flux_modulation_target_gnomic.old[0].type, 'flux') self.assertIsInstance(flux_modulation_target_gnomic.new, FeatureTree) self.assertIsInstance(flux_modulation_target_gnomic.new[0], Feature) self.assertEqual( flux_modulation_target_gnomic.new[0].accession.identifier, flux_modulation_target.id) self.assertEqual(flux_modulation_target_gnomic.new[0].type, 'flux') self.assertEqual( flux_modulation_target_gnomic.new[0].variant, "down-regulation(%f)" % flux_modulation_target.fold_change) flux_modulation_target = FluxModulationTarget("test", 0, 1) flux_modulation_target_gnomic = flux_modulation_target.to_gnomic() self.assertIsInstance(flux_modulation_target_gnomic, Mutation) self.assertIsInstance(flux_modulation_target_gnomic.old, FeatureTree) self.assertIsInstance(flux_modulation_target_gnomic.old[0], Feature) self.assertEqual( flux_modulation_target_gnomic.old[0].accession.identifier, flux_modulation_target.id) self.assertEqual(flux_modulation_target_gnomic.old[0].variant, None) self.assertEqual(flux_modulation_target_gnomic.old[0].type, 'flux') self.assertIs(flux_modulation_target_gnomic.new, None) reaction = Reaction(id="atpzase", name="Cosmic ATP generator") atp_z = Metabolite(id="atp_z", name="Cosmic ATP", compartment="c") reaction.add_metabolites({self.model.metabolites.atp_c: 1, atp_z: -1}) knockin_target = ReactionKnockinTarget("atpzase", reaction) knockin_target_gnomic = knockin_target.to_gnomic() self.assertIsInstance(knockin_target_gnomic, Mutation) self.assertIsInstance(knockin_target_gnomic.new, FeatureTree) self.assertIsInstance(knockin_target_gnomic.new[0], Feature) self.assertEqual(knockin_target_gnomic.new[0].accession.identifier, knockin_target.id) self.assertEqual(knockin_target_gnomic.new[0].variant, None) self.assertEqual(knockin_target_gnomic.new[0].type, 'reaction') self.assertIs(knockin_target_gnomic.old, None) cofactor_id_swaps = [("nad_c", "nadh_c"), ("nadp_c", "nadph_c")] swap_pairs = ([ self.model.metabolites.get_by_id(m) for m in cofactor_id_swaps[0] ], [self.model.metabolites.get_by_id(m) for m in cofactor_id_swaps[1]]) swap_target = ReactionCofactorSwapTarget("GAPD", swap_pairs) swap_target_gnomic = swap_target.to_gnomic() self.assertIsInstance(swap_target_gnomic, Mutation) self.assertIsInstance(swap_target_gnomic.old, FeatureTree) self.assertIsInstance(swap_target_gnomic.old[0], Feature) self.assertEqual(swap_target_gnomic.old[0].accession.identifier, swap_target.id) self.assertEqual(swap_target_gnomic.old[0].variant, None) self.assertEqual(swap_target_gnomic.old[0].type, 'reaction') self.assertIsInstance(swap_target_gnomic.new, FeatureTree) self.assertIsInstance(swap_target_gnomic.new[0], Feature) self.assertEqual(swap_target_gnomic.new[0].accession.identifier, swap_target.id + swap_target.swap_str) self.assertEqual(swap_target_gnomic.new[0].variant, None) self.assertEqual(swap_target_gnomic.new[0].type, 'reaction')
def test_gnomic_integration(self, model): from gnomic.models import Accession, Feature, Mutation, FeatureTree abstract_target = Target("test") abstract_target_gnomic = abstract_target.to_gnomic() assert isinstance(abstract_target_gnomic, Accession) assert abstract_target_gnomic.identifier == abstract_target.id flux_modulation_target = FluxModulationTarget("test", 1, 0) flux_modulation_target_gnomic = flux_modulation_target.to_gnomic() flux_mod_new = flux_modulation_target_gnomic.new flux_mod_old = flux_modulation_target_gnomic.old assert isinstance(flux_modulation_target_gnomic, Mutation) assert isinstance(flux_mod_old, FeatureTree) assert isinstance(flux_mod_old[0], Feature) assert flux_mod_old[ 0].accession.identifier == flux_modulation_target.id assert flux_mod_old[0].variant is None assert flux_mod_old[0].type == 'flux' assert isinstance(flux_mod_new, FeatureTree) assert isinstance(flux_mod_new[0], Feature) assert flux_mod_new[ 0].accession.identifier == flux_modulation_target.id assert flux_mod_new[0].type == 'flux' assert flux_mod_new[ 0].variant == "over-expression(%.3f)" % flux_modulation_target.fold_change flux_modulation_target = FluxModulationTarget("test", 0.5, 1) flux_modulation_target_gnomic = flux_modulation_target.to_gnomic() flux_mod_new = flux_modulation_target_gnomic.new flux_mod_old = flux_modulation_target_gnomic.old assert isinstance(flux_modulation_target_gnomic, Mutation) assert isinstance(flux_mod_old, FeatureTree) assert isinstance(flux_mod_old[0], Feature) assert flux_mod_old[ 0].accession.identifier == flux_modulation_target.id assert flux_mod_old[0].variant is None assert flux_mod_old[0].type == 'flux' assert isinstance(flux_mod_new, FeatureTree) assert isinstance(flux_mod_new[0], Feature) assert flux_mod_new[ 0].accession.identifier == flux_modulation_target.id assert flux_mod_new[0].type == 'flux' assert flux_mod_new[ 0].variant == "down-regulation(%.3f)" % flux_modulation_target.fold_change flux_modulation_target = FluxModulationTarget("test", 0, 1) flux_modulation_target_gnomic = flux_modulation_target.to_gnomic() assert isinstance(flux_modulation_target_gnomic, Mutation) assert isinstance(flux_modulation_target_gnomic.old, FeatureTree) assert isinstance(flux_modulation_target_gnomic.old[0], Feature) assert flux_modulation_target_gnomic.old[ 0].accession.identifier == flux_modulation_target.id assert flux_modulation_target_gnomic.old[0].variant is None assert flux_modulation_target_gnomic.old[0].type == 'flux' assert flux_modulation_target_gnomic.new is None reaction = Reaction(id="atpzase", name="Cosmic ATP generator") atp_z = Metabolite(id="atp_z", name="Cosmic ATP", compartment="c") reaction.add_metabolites({model.metabolites.atp_c: 1, atp_z: -1}) knockin_target = ReactionKnockinTarget("atpzase", reaction) knockin_target_gnomic = knockin_target.to_gnomic() assert isinstance(knockin_target_gnomic, Mutation) assert isinstance(knockin_target_gnomic.new, FeatureTree) assert isinstance(knockin_target_gnomic.new[0], Feature) assert knockin_target_gnomic.new[ 0].accession.identifier == knockin_target.id assert knockin_target_gnomic.new[0].variant is None assert knockin_target_gnomic.new[0].type == 'reaction' assert knockin_target_gnomic.old is None 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) swap_target_gnomic = swap_target.to_gnomic() assert isinstance(swap_target_gnomic, Mutation) assert isinstance(swap_target_gnomic.old, FeatureTree) assert isinstance(swap_target_gnomic.old[0], Feature) assert swap_target_gnomic.old[0].accession.identifier == swap_target.id assert swap_target_gnomic.old[0].variant is None assert swap_target_gnomic.old[0].type == 'reaction' assert isinstance(swap_target_gnomic.new, FeatureTree) assert isinstance(swap_target_gnomic.new[0], Feature) assert swap_target_gnomic.new[ 0].accession.identifier == swap_target.id + swap_target.swap_str assert swap_target_gnomic.new[0].variant is None assert swap_target_gnomic.new[0].type == 'reaction'
def _make_dual_model(self, model): dual_model = SolverBasedModel(solver_interface=model.solver.interface) # Add dual metabolites dual_metabolite_names = [] irreversibles = [] # Metabolites for which a z-reaction must be added self._dual_to_primal_mapping = {} for re in model.reactions: forward_id = re._get_forward_id() reverse_id = re._get_reverse_id() if forward_id in self._split_vars or reverse_id in self._split_vars: if re.upper_bound > 0 or forward_id in self._split_vars: dual_metabolite_names.append(forward_id) irreversibles.append(forward_id) self._dual_to_primal_mapping[forward_id] = re.id if re.lower_bound < 0 or reverse_id in self._split_vars: dual_metabolite_names.append(reverse_id) irreversibles.append(reverse_id) self._dual_to_primal_mapping[reverse_id] = re.id else: dual_metabolite_names.append(re.id) if re.lower_bound >= 0: irreversibles.append(re.id) self._dual_to_primal_mapping[re.id] = re.id dual_model.add_metabolites([Metabolite(name) for name in dual_metabolite_names]) # Add dual "u-reactions" transposed_stoichiometry = {} for reaction in model.reactions: for met, coef in reaction.metabolites.items(): if reaction._get_reverse_id() in dual_metabolite_names: transposed_stoichiometry.setdefault(met, {})[ dual_model.metabolites.get_by_id(reaction._get_reverse_id())] = -coef if reaction._get_forward_id() in dual_metabolite_names: transposed_stoichiometry.setdefault(met, {})[ dual_model.metabolites.get_by_id(reaction._get_forward_id())] = coef elif reaction.id in dual_metabolite_names: # This should be the same as forward_var.name but in general it might not be transposed_stoichiometry.setdefault(met, {})[ dual_model.metabolites.get_by_id(reaction.id)] = coef u_reactions = [] for met, stoichiometry in transposed_stoichiometry.items(): met_id = met.id reac = Reaction("u_" + met_id) reac.lower_bound = -reac.upper_bound # Make reversible reac.add_metabolites(stoichiometry) u_reactions.append(reac) dual_model.add_reactions(u_reactions) # Add dual "v-reactions" v_reactions = [] for dual_met in dual_model.metabolites: reac = Reaction("v_" + dual_met.id) reac.lower_bound = -reac.upper_bound # Make reversible reac.add_metabolites({dual_met: 1}) v_reactions.append(reac) dual_model.add_reactions(v_reactions) self._v_reactions = v_reactions # Add dual "z-reactions" z_reactions = [] for dual_met in dual_model.metabolites: if dual_met.id in irreversibles: reac = Reaction("z_" + dual_met.id) reac.lower_bound = 0 reac.add_metabolites({dual_met: -1}) z_reactions.append(reac) dual_model.add_reactions(z_reactions) return dual_model
def _make_dual_model(self, model): dual_model = SolverBasedModel(solver_interface=model.solver.interface) # Add dual metabolites dual_metabolite_names = [] irreversibles = [] # Metabolites for which a z-reaction must be added self._dual_to_primal_mapping = {} for re in model.reactions: forward_id = re._get_forward_id() reverse_id = re._get_reverse_id() if forward_id in self._split_vars or reverse_id in self._split_vars: if re.upper_bound > 0 or forward_id in self._split_vars: dual_metabolite_names.append(forward_id) irreversibles.append(forward_id) self._dual_to_primal_mapping[forward_id] = re.id if re.lower_bound < 0 or reverse_id in self._split_vars: dual_metabolite_names.append(reverse_id) irreversibles.append(reverse_id) self._dual_to_primal_mapping[reverse_id] = re.id else: dual_metabolite_names.append(re.id) if re.lower_bound >= 0: irreversibles.append(re.id) self._dual_to_primal_mapping[re.id] = re.id dual_model.add_metabolites( [Metabolite(name) for name in dual_metabolite_names]) # Add dual "u-reactions" transposed_stoichiometry = {} for reaction in model.reactions: for met, coef in reaction.metabolites.items(): if reaction._get_reverse_id() in dual_metabolite_names: transposed_stoichiometry.setdefault( met, {})[dual_model.metabolites.get_by_id( reaction._get_reverse_id())] = -coef if reaction._get_forward_id() in dual_metabolite_names: transposed_stoichiometry.setdefault( met, {})[dual_model.metabolites.get_by_id( reaction._get_forward_id())] = coef elif reaction.id in dual_metabolite_names: # This should be the same as forward_var.name but in general it might not be transposed_stoichiometry.setdefault( met, {})[dual_model.metabolites.get_by_id( reaction.id)] = coef u_reactions = [] for met, stoichiometry in transposed_stoichiometry.items(): met_id = met.id reac = Reaction("u_" + met_id) reac.lower_bound = -reac.upper_bound # Make reversible reac.add_metabolites(stoichiometry) u_reactions.append(reac) dual_model.add_reactions(u_reactions) # Add dual "v-reactions" v_reactions = [] for dual_met in dual_model.metabolites: reac = Reaction("v_" + dual_met.id) reac.lower_bound = -reac.upper_bound # Make reversible reac.add_metabolites({dual_met: 1}) v_reactions.append(reac) dual_model.add_reactions(v_reactions) self._v_reactions = v_reactions # Add dual "z-reactions" z_reactions = [] for dual_met in dual_model.metabolites: if dual_met.id in irreversibles: reac = Reaction("z_" + dual_met.id) reac.lower_bound = 0 reac.add_metabolites({dual_met: -1}) z_reactions.append(reac) dual_model.add_reactions(z_reactions) return dual_model