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)
예제 #3
0
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
예제 #5
0
 def __init__(self, metabolism):
     super(Metabolism2glpk, self).__init__()
     self.metabolism = metabolism
     self.stoich = StoichiometricMatrix()
     self.stoich.make_new_from_system(self.metabolism)
예제 #6
0
        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()