def allot_consistent_stoichiometry(graph, factors): """ @param graph: L{BipartiteMetabolicNetwork <pyMetabolism.graph_view.BipartiteMetabolicNetwork>} @param factors: An iterable of desired stoichiometric factors. May contain a specific factor multiple times to bias towards selection of that factor. @rtype: L{BipartiteMetabolicNetwork <pyMetabolism.graph_view.BipartiteMetabolicNetwork>} with consistent stoichiometric factors. """ options = OptionsManager() logger = logging.getLogger("%s.allot_consistent_stoichiometry"\ % options.main_logger_name) def populate_network(graph, factors): for e in graph.edges_iter(): graph[e[0]][e[1]]["factor"] = random.choice(factors) count = 0 while (True): count += 1 logger.info("Attempt number %d", count) populate_network(graph, factors) matrix = StoichiometricMatrix() matrix.make_new_from_network(graph) (yes, result) = verify_consistency(matrix) if yes: logger.info("Success!") break
def balance_multiple_reactions(graph, factors, rxns, mass_vector, lower, upper, logger): options = OptionsManager() sub = BipartiteMetabolicNetwork() for rxn in rxns: msg = "%s:\n" % rxn.identifier sub.add_reaction(rxn) for cmpd in graph.predecessors(rxn): coefficient = random.choice(factors) msg += " -%d%s" % (coefficient, cmpd) sub.add_compound(cmpd) sub.add_edge(cmpd, rxn, factor=coefficient) graph[cmpd][rxn]["factor"] = coefficient for cmpd in graph.successors(rxn): coefficient = random.choice(factors) msg += " +%d%s" % (coefficient, cmpd) sub.add_compound(cmpd) sub.add_edge(rxn, cmpd, factor=coefficient) graph[rxn][cmpd]["factor"] = coefficient msg += " = 0\n" logger.debug(msg) matrix = StoichiometricMatrix() matrix.make_new_from_network(sub) # objective function objective = numpy.ones(matrix.num_compounds) # equality constraints A_eq = numpy.array(numpy.transpose(matrix.matrix), dtype=float, copy=False) b_eq = numpy.zeros(matrix.num_reactions) # lower boundary lb = numpy.empty(matrix.num_compounds) for (i, comp) in enumerate(matrix.compounds): if mass_vector[comp] != 0.: lb[i] = mass_vector[comp] else: lb[i] = lower # upper boundary ub = numpy.empty(matrix.num_compounds) for (i, comp) in enumerate(matrix.compounds): if mass_vector[comp] != 0.: ub[i] = mass_vector[comp] else: ub[i] = upper # starting guess start = numpy.empty(matrix.num_compounds) logger.debug(A_eq) for (i, comp) in enumerate(matrix.compounds): start[i] = 1. / float(sub.in_degree(comp) + sub.out_degree(comp)) problem = openopt.LP(f=objective, Aeq=A_eq, beq=b_eq, lb=lb, ub=ub, x0=start) result = problem.solve(options.solver, iprint=-10) if not result.isFeasible: raise PyMetabolismError("Unable to balance reaction system.") for (i, comp) in enumerate(matrix.compounds): if mass_vector[comp] == 0.: mass_vector[comp] = result.xf[i] logger.debug(result.xf)
class Metabolism2glpk(object): """docstring for metabolism2glpk""" def __init__(self, metabolism): super(Metabolism2glpk, self).__init__() self.metabolism = metabolism self.stoich = StoichiometricMatrix() self.stoich.make_new_from_system(self.metabolism) def __stoich_to_sparse_triplet(self): """docstring for fname""" non_zero = self.stoich.matrix.nonzero() num_non_zero = len(non_zero[0]) non_zero_elements = self.stoich.matrix[non_zero] ia = intArray(num_non_zero) ja = intArray(num_non_zero) ar = doubleArray(num_non_zero) print non_zero for i in range(0, num_non_zero): ia[i+1] = int(non_zero[0][i] + 1.) ja[i+1] = non_zero[1][i] + 1 ar[i+1] = non_zero_elements[i] print num_non_zero print ia[1] return (num_non_zero, ia, ja, ar) def convert_to_ifba_metabolism(self): """docstring for convert_to_ifba_metabolism""" lp = glp_create_prob() (num_non_zero, ia, ja, ar) = self.__stoich_to_sparse_triplet() glp_add_rows(lp, self.stoich.num_compounds) glp_add_cols(lp, self.stoich.num_reactions) glp_load_matrix(lp, num_non_zero, ia, ja, ar) for i in range(self.stoich.num_compounds): rev_compound_map = dict((v,k) for k, v in self.stoich.compound_map.iteritems()) glp_set_row_name(lp, i+1, rev_compound_map[i].identifier+"_"+rev_compound_map[i].compartment.name) for i in range(self.stoich.num_reactions): rev_reaction_map = dict((v,k) for k, v in self.stoich.reaction_map.iteritems()) glp_set_col_name(lp, i+1, rev_reaction_map[i].identifier) fba_object = ifba.Metabolism(lp) col_bounds = dict() for r in self.metabolism: if r.reversible: print r col_bounds[r.identifier] = (-1000, 1000) else: col_bounds[r.identifier] = (0, 1000) fba_object.modifyColumnBounds(col_bounds) fba_object.modifyRowBounds(dict([(r, (0., 0.)) for r in fba_object.getRowIDs()])) return fba_object def convert_to_ifba_glpk(self): """docstring for convert_to_ifba_metabolism""" pass
def random_fba(graph, num_inputs, num_outputs): """ @param graph: BipartiteMetabolicNetwork @param num_inputs: Sequence of integers for a number of compound sources on the same set of sink compounds @param num_outputs: Size of the sink vector """ options = OptionsManager() logger = logging.getLogger("%s.random_fba" % options.main_logger_name) assert num_outputs > 0 if not num_inputs: raise PyMetabolismError("No sources specified for random FBA!") for input in num_inputs: assert input > 0 inputs = list() potential_inputs = list() outputs = list() results = list() cmpds = list(graph.compounds) for comp in graph.compounds: if len(outputs) < num_outputs and graph.out_degree(comp) == 0: outputs.append(comp) cmpds.remove(comp) elif graph.in_degree(comp) == 0: potential_inputs.append(comp) cmpds.remove(comp) # if necessary fill up 'outputs' with random compounds # they should not be source compounds, thus we remove references count = num_outputs - len(outputs) while (count > 0): comp = random.choice(cmpds) outputs.append(comp) cmpds.remove(comp) count -= 1 logger.info("%d biomass compounds.", len(outputs)) # perform FBA for varying numbers of source compounds matrix = StoichiometricMatrix() matrix.make_new_from_network(graph) # add biomass reaction biomass = Reaction("Biomass", tuple(outputs), (), [-1.]*num_outputs) # equality constraints b_eq = numpy.zeros(matrix.num_compounds) # start with the largest number of inputs, then reduce num_inputs.sort(reverse=True) maxi = num_inputs[0] for comp in potential_inputs: if len(inputs) < maxi: inputs.append(comp) # similarly to 'outputs', 'inputs' is filled up count = maxi - len(inputs) while (count > 0): comp = random.choice(cmpds) inputs.append(comp) cmpds.remove(comp) count -= 1 for num in num_inputs: system = numpy.array(matrix, dtype=float, copy=True) system.add_reaction(biomass) logger.info("%d uptake compounds.", num) input_rxns = list() # adjust source numbers while len(inputs) > num: comp = random.choice(inputs) inputs.remove(comp) transp = list() for comp in inputs: rxn = Reaction("Transport_%s" % comp.identifier,\ (), (comp), (1.), reversible=True) system.add_reaction(rxn) transp.append(rxn) # objective function objective = numpy.zeros(system.num_reactions) objective[system.reaction_map[biomass]] = 1. # equality constraints A_eq = system # prepare flux balance analysis linear programming problem # boundaries lb = numpy.zeros(system.num_reactions) for rxn in system.reactions: if rxn.reversible: lb[system.reaction_map[rxn]] = -numpy.inf ub = numpy.empty(system.num_reactions) ub.fill(numpy.inf) # constrain transport reactions for rxn in transp: ub[system.reaction_map[rxn]] = 1. lb[system.reaction_map[rxn]] = -1. problem = openopt.LP(f=objective, Aeq=A_eq, beq=b_eq, lb=lb, ub=ub) result = problem.maximize(options.solver, iprint=-10) logger.debug(result.xf) for rxn in graph.reactions: if rxn == biomass: logger.info("%s : %G", rxn.identifier, result.xf[system.reaction_map[rxn]]) elif rxn in transp: logger.info("%s : %G", rxn.identifier, result.xf[system.reaction_map[rxn]]) else: logger.info("%s : %G", rxn.identifier, result.xf[system.reaction_map[rxn]]) results.append((result.isFeasible, result.xf)) return results
def __init__(self, metabolism): super(Metabolism2glpk, self).__init__() self.metabolism = metabolism self.stoich = StoichiometricMatrix() self.stoich.make_new_from_system(self.metabolism)
return fba_object def convert_to_ifba_glpk(self): """docstring for convert_to_ifba_metabolism""" pass if __name__ == '__main__': import re smallModel = '../test_data/Ec_core_flux1.xml' bigModel = '../test_data/iAF1260.xml' parser = SBMLParser(smallModel, rprefix='R_', rsuffix='', cprefix='M_', csuffix=re.compile('_.$')) metbol = parser.get_metabolic_system() print metbol[0] s = StoichiometricMatrix() s.make_new_from_system(metbol) print s.matrix converter = Metabolism2glpk(metbol) lp = converter.convert_to_ifba_metabolism() print lp print lp.getColumnIDs() print lp.getObjectiveFunction() lp.simplex() print lp extra_mets = [m.get_id() for m in metbol.compounds if m.compartment == 'Extra_organism'] lp.freeMetabolites(extra_mets) lp.setOptFlag('Max') lp.setReactionObjective('Biomass_Ecoli_core_N__w_GAM_') print lp.getObjectiveFunction() print lp.fba()